ΠΠ·ΡΡΠΈΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½ Builder, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΏΡΠΎΡΠ°Π΅Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ»ΠΎΠΆΠ½ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΈ ΠΏΠΎΠ²ΡΡΠ°Π΅Ρ Π³ΠΈΠ±ΠΊΠΎΡΡΡ Π²Π°ΡΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ².
Π‘ΠΎΠ΄Π΅ΡΠΆΠ°Π½ΠΈΠ΅
- Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ Builder Pattern Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ React
- ΠΠ°ΠΊΠΎΠ²Ρ ΡΠ΅Π°Π»ΡΠ½ΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Builder Patterns Π² React
- Π‘ΡΠ΅Π½Π°ΡΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ 1: ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΡΠΎΡΠΌ Π² React Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠ°Π±Π»ΠΎΠ½Π° Builder
- Π‘ΡΠ΅Π½Π°ΡΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ 2. ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°Π±Π»ΠΎΠ½ Builder Π² React Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² ΡΠΎ ΡΠ»ΠΎΠΆΠ½ΡΠΌΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌΠΈ
- Π‘ΡΠ΅Π½Π°ΡΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ 3. ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Builder Pattern Π² React HOC ΠΈ Π½ΡΠΆΠ½ΠΎ Π»ΠΈ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ
- ΠΠ°ΠΊΠΎΠ²Ρ Π»ΡΡΡΠΈΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°Π±Π»ΠΎΠ½Π° Builder Π² React
- ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅
Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ 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
. submitCallback
function Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡ Π΄Π°Π½Π½ΡΠ΅ ΡΠΎΡΠΌΡ Π² ΠΊΠΎΠ½ΡΠΎΠ»Ρ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΡΠ΅Π½ΡΡΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΡ ΡΠΎΡΠΌ ΠΈ ΠΈΠ·Π±Π΅Π³Π°ΡΡ ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΡ ΠΊΠΎΠ΄Π°.
Π ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ 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 ReduxwithRouter
ΠΈΠ· React RouterwithTranslation
ΠΈΠ· 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. Π, ΠΏΠΎΠΆΠ°Π»ΡΠΉΡΡΠ°, Π½Π΅ ΡΡΠ΅ΡΠ½ΡΠΉΡΠ΅ΡΡ Π²ΡΡΠ°ΠΆΠ°ΡΡ ΡΠ²ΠΎΡ ΠΏΡΠΈΠ·Π½Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ, Ρ Π»ΠΎΠΏΠ°Ρ Π² Π»Π°Π΄ΠΎΡΠΈ, ΠΎΡΡΠ°Π²Π»ΡΡ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ, ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°ΡΡΡ ΠΈ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°ΡΡΡ. ΠΠ°ΠΆΠ΄ΡΠΉ Ρ Π»ΠΎΠΏΠΎΠΊ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΠΏΠΎΠ²ΡΡΠΈΡΡ ΡΠ·Π½Π°Π²Π°Π΅ΠΌΠΎΡΡΡ ΡΡΠ°ΡΡΠΈ, ΡΡΠΎ Π² ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΠΈΡΠΎΠ³Π΅ ΠΏΡΠΈΠ½ΠΎΡΠΈΡ ΠΏΠΎΠ»ΡΠ·Ρ ΡΠΎΠΎΠ±ΡΠ΅ΡΡΠ²Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π² ΡΠ΅Π»ΠΎΠΌ. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΎΡΠ»ΠΈΡΠ½ΡΠΉ ΡΠΏΠΎΡΠΎΠ± ΡΠ»ΡΡΡΠΈΡΡ ΡΠ²ΠΎΡ ΠΊΠ°ΡΠΌΡ. Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ Π·Π° ΡΡΠ΅Π½ΠΈΠ΅, ΠΈ ΠΌΡ Π½Π°Π΄Π΅Π΅ΠΌΡΡ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π²Π°Ρ ΡΠ½ΠΎΠ²Π° Π² Π±Π»ΠΈΠΆΠ°ΠΉΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ!