Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ шаблон Builder, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ созданиС слоТных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ Π²Π°ΡˆΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Builder Pattern Π² контСкстС React

ΠŸΡ€ΠΈΠ²Π΅Ρ‚, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, сСгодня ΠΌΡ‹ ΠΈΠ·ΡƒΡ‡ΠΈΠΌ Ρ€ΠΎΠ»ΡŒ Builder Pattern Π² Π΄ΠΈΠ·Π°ΠΉΠ½Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ React. Π¨Π°Π±Π»ΠΎΠ½ строитСля – это творчСский шаблон проСктирования, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ шаг Π·Π° шагом ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ слоТныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΡ€ΠΈ настройкС процСсса создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ позволяСт ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ создания Π±ΠΎΠ»ΡŒΡˆΠΈΡ… конструкторов ΠΈΠ»ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ². ΠžΡ‚Π΄Π΅Π»ΠΈΠ² ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΡ‚ Π΅Π³ΠΎ прСдставлСния, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ прСдставлСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Π’ React шаблон Builder ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для создания ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², состоящих ΠΈΠ· Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π»ΠΊΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚ΠΎΠ². Π­Ρ‚ΠΎ позволяСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ слоТныС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠ· Π±ΠΎΠ»Π΅Π΅ простых, дСлая ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΌ ΠΈ Π»Π΅Π³ΠΊΠΈΠΌ Π² обслуТивании. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ шаблон Builder Π² React, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠ΅ ΠΈ простыС Π² ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΌ использовании ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹.

ΠšΠ°ΠΊΠΎΠ²Ρ‹ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования Builder Patterns Π² React?

Π˜Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊΠΎΠ²Ρ‹ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования шаблона Builder Π² React?

  • Π§Ρ‚ΠΎ ΠΆ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠ½ΡƒΡŽ Π²Π΅Ρ‰ΡŒ β€” ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ слоТныС Ρ„ΠΎΡ€ΠΌΡ‹ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ ΠΈ стилСй. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Form Builder, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π² качСствС свойств ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΈΡ… с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΈ ΠΌΠ°ΠΊΠ΅Ρ‚ΠΎΠΌ. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ созданиС ΠΈ обслуТиваниС слоТных Ρ„ΠΎΡ€ΠΌ!
  • Π”Ρ€ΡƒΠ³ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ использования шаблона Builder β€” созданиС нСизмСняСмых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с большим количСством Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ². Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ слоТным, Π½ΠΎ это просто ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ User Builder для установки Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (имя, адрСс элСктронной ΠΏΠΎΡ‡Ρ‚Ρ‹, ΠΏΠ°Ρ€ΠΎΠ»ΡŒ, Ρ€ΠΎΠ»ΡŒ ΠΈ Ρ‚. Π΄.) ΠΈ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ с этими свойствами. Π­Ρ‚ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ созданиС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с мноТСством Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… свойств Π±Π΅Π· нСобходимости написания Ρ‚ΠΎΠ½Π½Ρ‹ ΠΊΠΎΠ΄Π°.
  • НаконСц, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ шаблон Builder для создания ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠ³ΠΎ использования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… сцСнариСв. НапримСр, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Card Builder, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ содСрТимоС, Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ ΠΈ Π½ΠΈΠΆΠ½ΠΈΠΉ ΠΊΠΎΠ»ΠΎΠ½Ρ‚ΠΈΡ‚ΡƒΠ»Ρ‹ ΠΈ ΡΡ‚ΠΈΠ»ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Ρ‹ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ ΠΈΡ… ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ. Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… Ρ€Π°Π·Π½Ρ‹Ρ… мСстах, Π½ΠΎ Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ выглядСл ΠΈ Π²Π΅Π» сСбя ΠΏΠΎ-Ρ€Π°Π·Π½ΠΎΠΌΡƒ.

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ использования 1: ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ конструктор Ρ„ΠΎΡ€ΠΌ Π² React с использованиСм шаблона Builder

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Form Builder β€” самый классичСский ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Builder Pattern Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΌΠΈΡ€Π΅ Π² Π²Π΅Π±-Π΄ΠΈΠ·Π°ΠΉΠ½Π΅. Π’ React это Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Ссли Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ динамичСски ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡ‹ Π½Π° основС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

import React from "react";

interface FormField {
  name: string;
  label: string;
  type: "text" | "password" | "email";
  required: boolean;
  value: string;
}

interface FormProps {
  fields: FormField[];
  onSubmit: (data: any) => void;
}

class FormBuilder {
  private fields: FormField[];

  constructor() {
    this.fields = [];
  }

  addField(name: string, label: string, type: "text" | "password" | "email") {
    this.fields.push({
      name,
      label,
      type,
      required: false,
      value: ""
    });

    return this;
  }

  makeRequired() {
    const lastField = this.fields[this.fields.length - 1];

    if (lastField) {
      lastField.required = true;
    }

    return this;
  }

  build(submitCallback): FormProps {
    return {
      fields: this.fields,
      onSubmit: submitCallback
    };
  }
}

function Form(props: FormProps) {
  const { fields, onSubmit } = props;

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    const formData = Object.fromEntries(new FormData(event.currentTarget));

    onSubmit(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      {fields.map(field => (
        <div key={field.name}>
          <label>
            {field.label}
            {field.required ? " *" : ""}
          </label>
          <input
            type={field.type}
            name={field.name}
            required={field.required}
            onChange={event => {
              field.value = event.currentTarget.value;
            }}
          />
        </div>
      ))}
      <button type="submit">Submit</button>
    </form>
  );
}

function App() {
  const form = useRef(new FormBuilder()
    .addField("firstName", "First name", "text")
    .addField("lastName", "Last name", "text")
    .addField("email", "Email", "email")
    .makeRequired()
    .build((data: any) => {
        console.log("Form submitted with data:", data);
    }));

  return (
    <div>
      <h1>Sign up form</h1>
      <Form {...form.current} />
    </div>
  );
}

export default App;

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ опрСдСляСм Π΄Π²Π° интСрфСйса: FormField для описания ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ поля Π² Ρ„ΠΎΡ€ΠΌΠ΅ ΠΈ FormProps для описания свойств, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Ρ„ΠΎΡ€ΠΌΡ‹.

Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ опрСдСляСм FormBuilder class, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ слСдуСт ΡˆΠ°Π±Π»ΠΎΠ½Ρƒ Builder. Класс FormBuilder ΠΈΠΌΠ΅Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ для добавлСния ΠΏΠΎΠ»Π΅ΠΉ Π² Ρ„ΠΎΡ€ΠΌΡƒ, ΠΏΠΎΠΌΠ΅Ρ‚ΠΊΠΈ послСднСго поля ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΈ создания ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚ΠΎΠ² Ρ„ΠΎΡ€ΠΌΡ‹. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ класс для создания Ρ„ΠΎΡ€ΠΌΡ‹, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ процСсс Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠΌ ΠΈ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ Π² сопровоТдСнии.

Π’ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ сборки FormBuilder ΠΌΡ‹ опрСдСляСм onSubmit, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ submitCallback. submitCallbackfunction Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΡ‹ Π² консоль. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ Ρ„ΠΎΡ€ΠΌ ΠΈ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ повторСния ΠΊΠΎΠ΄Π°.

Π’ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ прилоТСния ΠΌΡ‹ создаСм Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр FormBuilder, добавляСм Π² Π½Π΅Π³ΠΎ Ρ‚Ρ€ΠΈ поля, ΠΏΠΎΠΌΠ΅Ρ‡Π°Π΅ΠΌ послСднСС ΠΏΠΎΠ»Π΅ ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΈ создаСм Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚Ρ‹ Ρ„ΠΎΡ€ΠΌΡ‹. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ свойства Ρ„ΠΎΡ€ΠΌΡ‹ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ Form ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π΅Π³ΠΎ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ вмСстС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ FormBuilder ΠΈ Form, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ динамичСский ΠΈ настраиваСмый ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒ Ρ„ΠΎΡ€ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… контСкстах.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для дСмонстрационных Ρ†Π΅Π»Π΅ΠΉ, Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ ΠΆΠΈΠ·Π½ΠΈ Π²Π°ΠΌ, скорСС всСго, потрСбуСтся большС настроСк ΠΈ стилСй.

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ использования 2. Как ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ шаблон Builder Π² React для создания ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² со слоТными свойствами

ΠŸΠΎΠ·Π²ΠΎΠ»ΡŒΡ‚Π΅ ΠΌΠ½Π΅ Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ шаблон Builder для упрощСния создания ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° с Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ свойствами. Π‘Π½Π°Ρ‡Π°Π»Π° посмотритС Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

import React from "react";

interface UserProps {
  firstName?: string;
  lastName?: string;
  email?: string;
  avatarUrl?: string;
}

class UserBuilder {
  private props: UserProps;

  constructor() {
    this.props = {};
  }

  withFirstName(firstName: string): UserBuilder {
    this.props.firstName = firstName;
    return this;
  }

  withLastName(lastName: string): UserBuilder {
    this.props.lastName = lastName;
    return this;
  }

  withEmail(email: string): UserBuilder {
    this.props.email = email;
    return this;
  }

  withAvatarUrl(avatarUrl: string): UserBuilder {
    this.props.avatarUrl = avatarUrl;
    return this;
  }

  build(): JSX.Element {
    return <User {...this.props} />;
  }
}

function User(props: UserProps) {
  return (
    <div>
      {props.avatarUrl && <img src={props.avatarUrl} alt="Avatar" />}
      {props.firstName && <p>{props.firstName}</p>}
      {props.lastName && <p>{props.lastName}</p>}
      {props.email && <p>{props.email}</p>}
    </div>
  );
}

function App() {
  const user1 = new UserBuilder().withFirstName("John").withEmail("[email protected]").build();
  const user2 = new UserBuilder().withFirstName("Jane").withLastName("Doe").withAvatarUrl("https://example.com/avatar.jpg").build();

  return (
    <div>
      {user1}
      {user2}
    </div>
  );
}

export default App;

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΌΡ‹ опрСдСляСм интСрфСйс UserProps, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит всС Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ свойства. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ создаСм класс User с этими свойствами Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² конструктора.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ User с шаблоном Builder, ΠΌΡ‹ опрСдСляСм класс UserBuilder с ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ свойства. Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ свойства ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ сам экзСмпляр UserBuilder, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ. НаконСц, ΠΌΡ‹ опрСдСляСм ΠΌΠ΅Ρ‚ΠΎΠ΄ сборки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ User со значСниями, установлСнными ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ построитСля.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ User с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ свойствами, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр класса UserBuilder, Π·Π°Π΄Π°Ρ‚ΡŒ Π½ΡƒΠΆΠ½Ρ‹Π΅ свойства с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Ρ‰ΠΈΠΊΠ° ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ сборки, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ User. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ User Π² качСствС Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΌΡƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ с прСдоставлСнными свойствами.

ИспользованиС шаблона Builder позволяСт Π½Π°ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ экзСмпляры ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° User Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с Π½ΡƒΠΆΠ½Ρ‹ΠΌΠΈ свойствами, Π±Π΅Π· нСобходимости ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ свойства Π² Π²ΠΈΠ΄Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚ΠΎΠ². Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ наш ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΠΊΡ€Π°Ρ‚ΠΊΠΈΠΌ ΠΈ простым Π² обслуТивании.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ: Π·Π°Ρ‡Π΅ΠΌ Π½Π°ΠΌ Π²ΠΎΠΎΠ±Ρ‰Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ ​​цСпочку свойств, Ссли ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ просто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΊΠ°ΠΊ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°?

ИспользованиС Builder Pattern даст Π²Π°ΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ прСимущСства, ΠΊΠΎΠ³Π΄Π°:

  • с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ происходит нСкоторая Π»ΠΎΠ³ΠΈΠΊΠ°, ΠΈ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π΅Π΅ Π°Π±ΡΡ‚Ρ€Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ.
  • Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΠ΅ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ увСличСния вашСго JSX, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΈΡ… Π² Π±ΠΈΠ»Π΄Π΅Ρ€.

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ использования 3. Как ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Builder Pattern Π² React HOC ΠΈ Π½ΡƒΠΆΠ½ΠΎ Π»ΠΈ это Π΄Π΅Π»Π°Ρ‚ΡŒ

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Ρ‹ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с HOC. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²Ρ‹ΡΡˆΠ΅Π³ΠΎ порядка. Π­Ρ‚ΠΎ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ° React для ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ использования Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ². HOC β€” это функция, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚.

НСкоторыС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ HOC:

  • connect ΠΈΠ· React Redux
  • withRouter ΠΈΠ· React Router
  • withTranslation ΠΈΠ· React i18next

ИспользованиС Builder Pattern ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ даст Π½Π°ΠΌ большС абстракции ΠΈ удобочитаСмости, Π½ΠΎ стоит Π»ΠΈ это Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… усилий? Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€. Допустим, Ρƒ нас Π΅ΡΡ‚ΡŒ Π»ΠΎΠ³ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ HOC, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΡƒΠΏΠ°ΠΊΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ Π½Π° консоль. ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ класс построитСля, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π½Π°ΠΌ Π»Π΅Π³ΠΊΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ экзСмпляры HOC с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ вСдСния ΠΆΡƒΡ€Π½Π°Π»Π°.

import React from "react";

interface LoggingOptions {
  logRender: boolean;
  logProps: boolean;
}

export function withLogging<P extends object>(
  Component: React.ComponentType<P>,
  loggingOptions: LoggingOptions
): React.ComponentType<P> {
  const { logRender, logProps } = loggingOptions;

  const componentName = Component.displayName || Component.name || "Component";

  return function WithLogging(props: P) {
    if (logRender) {
      console.log(`Rendering component: ${componentName}`);
    }

    if (logProps) {
      console.log(`Component props: ${JSON.stringify(props)}`);
    }

    return <Component {...props} />;
  };
}

interface HOCBuilderOptions {
  logRender: boolean;
  logProps: boolean;
}

class LoggingHOCBuilder {
  private options: HOCBuilderOptions;

  constructor() {
    this.options = {
      logRender: false,
      logProps: false,
    };
  }

  withLogRender(logRender: boolean): LoggingHOCBuilder {
    this.options.logRender = logRender;
    return this;
  }

  withLogProps(logProps: boolean): LoggingHOCBuilder {
    this.options.logProps = logProps;
    return this;
  }

  build<P extends object>(Component: React.ComponentType<P>): React.ComponentType<P> {
    return withLogging(Component, this.options);
  }
}

function MyComponent(props: { name: string }) {
  return (
    <div>
      Hello, {props.name}!
    </div>
  );
}

const LoggedMyComponent = new LoggingHOCBuilder()
  .withLogRender(true)
  .withLogProps(true)
  .build(MyComponent);

function App() {
  return (
    <div>
      <LoggedMyComponent name="Alice" />
      <LoggedMyComponent name="Bob" />
    </div>
  );
}

export default App;

Π­Ρ‚ΠΎ ΡƒΠΆΠ΅ выглядит Π²Π΅Π»ΠΈΠΊΠΎΠ»Π΅ΠΏΠ½ΠΎ, ΠΈ Builder Pattern ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΠΈΠ» свои потрСбности, Π½ΠΎ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π²Π°ΡˆΡƒ ΠΈΠ½Ρ‚ΡƒΠΈΡ†ΠΈΡŽ ΠΏΠΎΡ‡ΡƒΠ²ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ с этим Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π΅ Ρ‚Π°ΠΊ. И Π΄Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ синтаксис Π½Π΅ выглядит ΠΎΡ‡Π΅Π½ΡŒ СстСствСнным ΠΈ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹ΠΌ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² React, особСнно для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ Π·Π½Π°ΠΊΠΎΠΌ с Decorators. Decorators ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, класс, ΠΌΠ΅Ρ‚ΠΎΠ΄, свойство ΠΈ Ρ‚.Β Π΄.), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅. Π’ Typescript ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ прСфикс @ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΊ Ρ†Π΅Π»Π΅Π²ΠΎΠΌΡƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ. Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Ρ€Π°Π·Π½ΠΈΡ†Ρƒ:

import React from "react";

interface LoggingOptions {
  logRender: boolean;
  logProps: boolean;
}

function withLogging<P extends object>(
  Component: React.ComponentType<P>,
  loggingOptions: LoggingOptions
): React.ComponentType<P> {
  const { logRender, logProps } = loggingOptions;

  const componentName = Component.displayName || Component.name || "Component";

  class WithLogging extends React.Component<P> {
    componentDidMount() {
      if (logRender) {
        console.log(`Rendering component: ${componentName}`);
      }
      if (logProps) {
        console.log(`Component props: ${JSON.stringify(this.props)}`);
      }
    }

    render() {
      return <Component {...this.props} />;
    }
  }

  WithLogging.displayName = `WithLogging(${componentName})`;

  return WithLogging;
}

interface WithLoggingOptions {
  logRender: boolean;
  logProps: boolean;
}

function WithLogging(options: WithLoggingOptions) {
  return function<T extends new (...args: any[]) => {}>(constructor: T) {
    return class extends constructor {
      constructor(...args: any[]) {
        super(...args);
        withLogging(this, options);
      }
    };
  };
}

interface MyComponentProps {
  name: string;
}

@WithLogging({ logRender: true, logProps: true })
class MyComponent extends React.Component<MyComponentProps> {
  render() {
    return (
      <div>
        Hello, {this.props.name}!
      </div>
    );
  }
}

function App() {
  return (
    <div>
      <MyComponent name="Alice" />
      <MyComponent name="Bob" />
    </div>
  );
}

export default App;

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ всС Π΅Ρ‰Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ TypeScript. Π§Ρ‚ΠΎΠ±Ρ‹ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ компилятора experimentalDecorators Π»ΠΈΠ±ΠΎ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкС, Π»ΠΈΠ±ΠΎ Π² Ρ„Π°ΠΉΠ»Π΅ tsconfig.json.

ΠšΠ°ΠΊΠΎΠ²Ρ‹ Π»ΡƒΡ‡ΡˆΠΈΠ΅ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ шаблона Builder Π² React

Π’ΠΎΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π»ΡƒΡ‡ΡˆΠΈΡ… ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊ использования шаблона Builder Π² React:

  • ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Ρ‰ΠΈΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ простыми ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΌΠΈ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ мСньшиС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ для создания Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΈ ΠΈΠ·Π±Π΅Π³Π°ΠΉΡ‚Π΅ создания слоТной Π»ΠΎΠ³ΠΈΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Π°ΡˆΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Ρ‰ΠΈΠΊΠ°.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚Ρ‹ для настройки ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² вашСго конструктора ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎ Π΄Π΅Ρ€Π΅Π²Ρƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ². Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ использования состояния ΠΈΠ»ΠΈ контСкста Π±Π΅Π· нСобходимости.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ составныС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π±ΠΎΠ»Π΅Π΅ высокого порядка, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Ρ‰ΠΈΠΊΠ° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями ΠΈΠ»ΠΈ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ. НапримСр, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ withValidation HOC для добавлСния Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΊ вашим ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌ Π²Π²ΠΎΠ΄Π° ΠΈΠ»ΠΈ withLogging для добавлСния ΠΆΡƒΡ€Π½Π°Π»ΠΎΠ².

ΠœΡ‹ надССмся, Ρ‡Ρ‚ΠΎ эта ΡΡ‚Π°Ρ‚ΡŒΡ оказалась для вас ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ ΠΈ ΠΏΡ€ΠΎΠ±ΡƒΠ΄ΠΈΠ»Π° вашС Π»ΡŽΠ±ΠΎΠΏΡ‹Ρ‚ΡΡ‚Π²ΠΎ ΠΏΠΎ ΠΏΠΎΠ²ΠΎΠ΄Ρƒ использования шаблона проСктирования Builder Π² React. И, поТалуйста, Π½Π΅ ΡΡ‚Π΅ΡΠ½ΡΠΉΡ‚Π΅ΡΡŒ Π²Ρ‹Ρ€Π°ΠΆΠ°Ρ‚ΡŒ свою ΠΏΡ€ΠΈΠ·Π½Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, хлопая Π² ладоши, оставляя ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ, ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡΡΡŒ ΠΈ ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡΡΡŒ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ…Π»ΠΎΠΏΠΎΠΊ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΡƒΠ·Π½Π°Π²Π°Π΅ΠΌΠΎΡΡ‚ΡŒ ΡΡ‚Π°Ρ‚ΡŒΠΈ, Ρ‡Ρ‚ΠΎ Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ ΠΈΡ‚ΠΎΠ³Π΅ приносит ΠΏΠΎΠ»ΡŒΠ·Ρƒ сообщСству Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Π² Ρ†Π΅Π»ΠΎΠΌ. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, это ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ способ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ свою ΠΊΠ°Ρ€ΠΌΡƒ. Бпасибо Π·Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, ΠΈ ΠΌΡ‹ надССмся ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ вас снова Π² блиТайшСС врСмя!





Π£Π·Π½Π°Ρ‚ΡŒ большС