рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд┐рдХрд╛рд╕ рдХрднреА-рдХрднреА рдПрдХ рдЬрд╛рд╕реВрд╕ рдХреА рддрд░рд╣ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдХрд┐рд╕реА рдФрд░ рдХреЗ рдХреЛрдб рдХреЛ рдХреИрд╕реЗ рд╕рдордЭреЗрдВ? рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдЕрдЧрд░ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдкрд╛рд╕ рдирд╛рдордХрд░рдг рдЪрд░ рдХрд╛ рд╕реВрдХреНрд╖реНрдо рдХреМрд╢рд▓ рд╣реИ рддрд╛рдХрд┐ рджреВрд╕рд░реЛрдВ рдХреЛ рдмрд╛рдд рд╕рдордЭ рдореЗрдВ рдЖрдПред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЯреАрдо рдХреЗ рд╕рджрд╕реНрдп рдЕрднреА рднреА рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧреА рдХреЗ рдЗрд░рд╛рджреЗ рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИрдВ? рдХреИрд╕реЗ рд╕рдордЭреЗрдВ рдХрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рдореЗрдВ рдХреНрдпрд╛ рдЖрддрд╛ рд╣реИ?


рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рдХреЛ рддреНрд░реБрдЯрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рдВрднрд╡рддрдГ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдореЗрдВ рдПрдХ рд╕рд░рдгреА рд╣реИред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд▓рд╛рдЗрдиреЗрдВ? рдЦреИрд░, рдпрд╣ рд╕рд░рдгреА рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рдЗрд╕рдХреА рд▓рдВрдмрд╛рдИ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд▓рдВрдмрд╛рдИ рдХреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рднреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рд▓рдЧрд╛рдиреЗ рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдлрд┐рд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпреВрдЖрдИ рдкрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдирд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдлреЙрд░реНрдо рдХреЗ рдЕрдВрддрд┐рдо рдЪрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред рдЕрдм рджреЗрд╡рдЯреВрд▓реЛрдВ рдореЗрдВ рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд▓рдВрдмрд╛рдИ рдХреНрд╖реЗрддреНрд░ рд╕рд╣рд┐рдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдПрдХ рд╡рд╕реНрддреБ рд╣реИрдВред


рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдореЗрдВ рдРрд╕реА рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рдбреЗрд╡рд▓рдкрд░ рд╕рдордп рдХреА рдмрд░реНрдмрд╛рджреА рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ (рдЗрд╕рдХреЗ рдмрд╛рдж ts) рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рдЗрд╕реЗ рдЕрдЧрд▓реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЗрд╕рд╕реЗ рднреА рдмреЗрд╣рддрд░, рдореМрдЬреВрджрд╛ рдореЗрдВ ts рд╕рдорд░реНрдерди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдХрд┐рд╕реА рдФрд░ рдХреЗ рдХреЛрдб рдХреЛ рд╕рдордЭрдиреЗ рдХрд╛ рд╕рдордп рдХрд╛рдлреА рдХрдо рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рджрд░рдЕрд╕рд▓, рдХрд┐рд╕реА рднреА рдбреЗрдЯрд╛ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреНрд▓рд┐рдХ рд╣реА рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдЖрдк рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реНрдХ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрд┐рд╕реА рднреА рд╕рдордп рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдХреЛрдб рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдордЭрддреЗ рд╣реИрдВред


Ts рдХреЗ рдХреБрдЫ рдлрд╛рдпрджреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рд╡рд┐рднрд┐рдиреНрди рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рдирд┐рдХрдЯрддрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред Ts рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдлреНрд░рдВрдЯрдПрдВрдб рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреА рдЬрд░реВрд░рддреЛрдВ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИред


рдпрд╣ рд▓реЗрдЦ рдЯреВрдбреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рджрд┐рд▓рдЪрд╕реНрдк рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдгред рдкреВрд░реНрдг рдХреЛрдб рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред


рдореИрдВрдиреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдореЛрдмрд╛рдЗрд▓ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред Mobx рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕реНрдерд┐рддрд┐ рдХреЗ рдкреНрд░рдмрдВрдзрди рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рдЪреАрд▓рд╛ рдЙрдкрдХрд░рдг рд╣реИред Mobx рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╢реИрд▓реА рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХреЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЬреИрд╕реЗ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ:


this.setState({name: 'another string'}); alert(this.state.name); 

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдкреБрд░рд╛рдирд╛ рд╕реНрдерд┐рддрд┐ .рдирд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддрд╛ рд╣реИред


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, mobx рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдФрд░ ts рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЖрдк рд░рд╛рдЬреНрдп рдХреЛ рдЕрд▓рдЧ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╛ рд╕реАрдзреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рд╕рднреА рдШрдЯрдХреЛрдВ рдХреЛ рдШрдЯрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдШрдЯрдХ рдХреЗ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдХреЛ рд░рд╛рдЬреНрдп рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдШрдЯрдХ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдФрд░ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд╛рде рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред


TodoItem рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ TodoItem.tsx, TodoItem.module.scss рд╢реИрд▓рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рдФрд░ рдПрдХ TodoItemState.ts рд╕реНрдерд┐рддрд┐ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╣реЛрддреА рд╣реИред


TodoItemState.ts рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ, рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЗ рд▓рд┐рдП рдлрд╝реАрд▓реНрдб рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред OOP рдФрд░ ts рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреА рд╢реНрд░реЗрдгреА рдмрд╣реБрдд рдмрдбрд╝реА рд╣реИред рдбреЗрдЯрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд┐рдЬреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рднрд╛рдЧ рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдФрд░ рдЗрд╕реА рддрд░рд╣ред @O рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рдлрд╝реАрд▓реНрдб рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рд░рд┐рдПрдХреНрдЯ рдШрдЯрдХ рдЙрдирдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ рд╣реИрдВред рд░рд╛рдЬреНрдп рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдореЗрдВ @ рдП ( рдПрдХреНрд╢рди ) рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


 // TodoItemState.ts import { action as a, observable as o } from 'mobx'; export interface ITodoItem { id: string; name: string; completed: boolean; } export class TodoItemState { @o public readonly value: ITodoItem; @o public isEditMode: boolean = false; constructor(value: ITodoItem) { this.value = value; } @a public setIsEditMode = (value: boolean = true) => { this.isEditMode = value; }; @a public editName = (name: string) => { this.value.name = name; }; @a public editCompleted = (completed: boolean) => { this.value.completed = completed; }; } 

TodoItem.tsx рдореЗрдВ, рдХреЗрд╡рд▓ рджреЛ рдЧреБрдгреЛрдВ рдХреЛ рд╕рд╣рд╛рд░рд╛ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореЛрдмреЗрдХреНрд╕ рдореЗрдВ, рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдкреНрд░реЙрдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡реЗрджрди рдХреЗ рд╕рдордЧреНрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдпрд╣ рдЗрд╖реНрдЯрддрдо рд╣реИред рдЪреВрдБрдХрд┐ рд╣рдо ts рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдШрдЯрдХ рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡реАрдХреГрдд рд╡рд╕реНрддреБ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдареАрдХ рд╕реЗ рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


 // TodoItem.tsx import React, { ChangeEventHandler } from 'react'; import { observer } from 'mobx-react'; import { TodoItemState } from './TodoItemState'; import { EditModal } from 'components/EditModal'; import classNames from 'classnames'; import classes from './TodoItem.module.scss'; export interface ITodoItemProps { todo: TodoItemState; onDelete: (id: string) => void; } @observer export class TodoItem extends React.Component<ITodoItemProps> { private handleCompletedChange: ChangeEventHandler<HTMLInputElement> = e => { const { todo: { editCompleted }, } = this.props; editCompleted(e.target.checked); }; private handleDelete = () => { const { onDelete, todo } = this.props; onDelete(todo.value.id); }; private get editModal() { const { todo } = this.props; if (!todo.isEditMode) return null; return ( <EditModal name={todo.value.name} onSubmit={this.handleSubmitEditName} onClose={this.closeEditModal} /> ); } private handleSubmitEditName = (name: string) => { const { todo } = this.props; todo.editName(name); this.closeEditModal(); }; private closeEditModal = () => { const { todo } = this.props; todo.setIsEditMode(false); }; private openEditModal = () => { const { todo } = this.props; todo.setIsEditMode(); }; render() { const { todo } = this.props; const { name, completed } = todo.value; return ( <div className={classes.root}> <input className={classes.chackbox} type="checkbox" checked={completed} onChange={this.handleCompletedChange} /> <div onClick={this.openEditModal} className={classNames( classes.name, completed && classes.completedName )}> {name} </div> <button onClick={this.handleDelete}>del</button> {this.editModal} </div> ); } } 

ITodoItemProps рдЗрдВрдЯрд░рдлрд╝реЗрд╕, TodoItemState рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░, рд╣рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдФрд░ рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрджрд▓рддреЗ рдбреЗрдЯрд╛ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рд░рд╛рдЬреНрдп рдХрдХреНрд╖рд╛ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдЯреЛрдбреЛ рд▓рд┐рд╕реНрдЯ рдШрдЯрдХ рдЯреЛрдбреЛрдЗрдЯреЗрдо рдХреЗ рд╕рдорд╛рди рд╣реИред TodoListState.ts рдореЗрдВ, рдЖрдк @c (@computed) рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдЧреЗрдЯрд░реНрд╕ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпреЗ рд╕рд╛рдзрд╛рд░рдг рд╢реНрд░реЗрдгреА рдХреЗ рдЧреЗрдЯрд░реНрд╕ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЙрдирдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдпрд╛рдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреА рдирд┐рд░реНрднрд░рддрд╛ рдореЗрдВ рдмрджрд▓рд╛рд╡ рд╣реЛрдиреЗ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рдЬрд╛рддреА рд╣реИред рдбрд┐рдЬрд╝рд╛рдЗрди рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рд░реЗрдбреНрдпреВрдХреНрд╕ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рдорд╛рди рд╣реИред рдЖрд╕рд╛рдиреА рд╕реЗ, рдпрд╣ рдирд┐рд░реНрднрд░рддрд╛ рдХреА рд╕реВрдЪреА рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, React.memo рдпрд╛ reselect рдХреА рддрд░рд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдШрдЯрдХ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдореВрд▓реНрдп рдХреА рдкреБрдирд░реНрдЧрдгрдирд╛ рддрдм рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдпрджрд┐ рдЧрдгрдирд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдкреНрд░рддрд┐рдкрд╛рджрди рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ (рдЬреЛ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ)ред рдЗрд╕рд▓рд┐рдП, рдирд┐рд░рдВрддрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЧрдгрдирд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ (рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдореВрд▓реНрдп рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдореЛрдмрд╛рдЗрд▓ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрддрд╛рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ)ред


 // TodoListState.ts import { action as a, observable as o, computed as c } from 'mobx'; import { ITodoItem, TodoItemState } from 'components/TodoItem'; export enum TCurrentView { completed, active, all, } export class TodoListState { @o public currentView: TCurrentView = TCurrentView.all; @o private _todos: TodoItemState[] = []; @c public get todos(): TodoItemState[] { switch (this.currentView) { case TCurrentView.active: return this.activeTodos; case TCurrentView.completed: return this.completedTodos; default: return this._todos; } } @c public get completedTodos() { return this._todos.filter(t => t.value.completed); } @c public get activeTodos() { return this._todos.filter(t => !t.value.completed); } @a public setTodos(todos: ITodoItem[]) { this._todos = todos.map(t => new TodoItemState(t)); } @a public addTodo = (todo: ITodoItem) => { this._todos.push(new TodoItemState(todo)); }; @a public removeTodo = (id: string): boolean => { const index = this._todos.findIndex(todo => todo.value.id === id); if (index === -1) return false; this._todos.splice(index, 1); return true; }; } 

рдкреНрд░рд╡реЗрд╢ рдЯреВрдбреВ рд╕реВрдЪреА рдХреЗрд╡рд▓ рдПрдХ рдЧрдгрдирд╛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЦреБрд▓реА рд╣реИ, рдЬрд╣рд╛рдВ, рджреЗрдЦрдиреЗ рдХреЗ рдореЛрдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЖрд╡рд╢реНрдпрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЛ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдкреВрд░рд╛, рд╕рдХреНрд░рд┐рдп рдпрд╛ рд╕рднреА рдЯреВрдбреВ)ред рдЯреВрдбреЛ рдирд┐рд░реНрднрд░рддрд╛ рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдкреВрд░реНрдгрдЯреЛрдбреЛрд╕, рд╕рдХреНрд░рд┐рдпрдЯреЛрдбреЛрд╕ рдФрд░ рдирд┐рдЬреА рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп _todos рдлрд╝реАрд▓реНрдб рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИрдВред


рдРрдк рдХреЗ рдореБрдЦреНрдп рдШрдЯрдХ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдпрд╣ рдирдП рдЯреВрдбреВ рдФрд░ рдЯреВрдбреВ рд╕реВрдЪреА рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд░реВрдк рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдореБрдЦреНрдп AppSate рд░рд╛рдЬреНрдп рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рддреБрд░рдиреНрдд рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


 // App.tsx import React from 'react'; import { observer } from 'mobx-react'; import { TodoList, initialTodos } from 'components/TodoList'; import { AddTodo } from 'components/AddTodo'; import { AppState } from './AppState'; import classes from './App.module.scss'; export interface IAppProps {} @observer export class App extends React.Component<IAppProps> { private appState = new AppState(); constructor(props: IAppProps) { super(props); this.appState.todoList.setTodos(initialTodos); } render() { const { addTodo, todoList } = this.appState; return ( <div className={classes.root}> <div className={classes.container}> <AddTodo onAdd={addTodo} /> <TodoList todoListState={todoList} /> </div> </div> ); } } 

AppState рдлрд╝реАрд▓реНрдб рдореЗрдВ TodoListState рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ TodoList рдШрдЯрдХ рдФрд░ рдирдП todo рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддреА рд╣реИ, рдЬреЛ AddTodo рдШрдЯрдХ рдХреЛ рджреА рдЬрд╛рддреА рд╣реИред


 // AppState.ts import { action as a } from 'mobx'; import { TodoListState } from 'components/TodoList'; import { ITodoItem } from 'components/TodoItem'; export class AppState { public todoList = new TodoListState(); @a public addTodo = (value: string) => { const newTodo: ITodoItem = { id: Date.now().toString(), name: value, completed: false, }; this.todoList.addTodo(newTodo); }; } 

AddTodo рдШрдЯрдХ рдореЗрдВ рдПрдХ рдкреГрдердХ рд╕реНрдерд┐рддрд┐ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рд░рд╛рдЬреНрдп рд╕реЗ рдЗрд╕рдХреА рдХреЛрдИ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИред AppState рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдХрдиреЗрдХреНрд╢рди рдПрдХ рдлреЙрд░реНрдо рд╕рдмрдорд┐рдЯ рдХрд░рддреЗ рд╕рдордп appState.addTodo рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрддрд╛ рд╣реИред
AddTodo рдШрдЯрдХ рдХреЗ рд░рд╛рдЬреНрдп рдХреЗ рд▓рд┐рдП, рдлреЙрд░реНрдорд╕реНрдЯреЗрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ ts рдФрд░ mobx рдХреЗ рд╕рд╛рде рдорд╣рд╛рди рджреЛрд╕реНрдд рд╣реИрдВред рдлрд╝реЙрд░реНрдореЗрдЯ рдЖрдкрдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдлрд╝реЙрд░реНрдо, рдорд╛рдиреНрдп рдлрд╝реЙрд░реНрдо рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдкреНрд░рдкрддреНрд░ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдЖрд╡рд╢реНрдпрдХ рдлрд╝реАрд▓реНрдб рдирд╛рдо рд╣реИред


 // AddTodoState.ts import { FormState, FieldState } from 'formstate'; export class AddTodoState { // Create a field public name = new FieldState('').validators( val => !val && 'name is required' ); // Compose fields into a form public form = new FormState({ name: this.name, }); public onSubmit = async () => { // Validate all fields const res = await this.form.validate(); // If any errors you would know if (res.hasError) { console.error(this.form.error); return; } const name = this.name.$; this.form.reset(); return name; }; } 

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕рднреА рдШрдЯрдХреЛрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИред рдкреВрд░рд╛ рдХреЛрдб рдпрд╣рд╛рдБ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред


рдпрд╣ рд▓реЗрдЦ рд▓реЗрдЦрдХ рдХреЗ рд╕рд░рд▓, рд▓рдЪреАрд▓реЗ рдФрд░ рд╕рдВрд░рдЪрд┐рдд рдХреЛрдб рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред рд░рд┐рдПрдХреНрдЯ рдпреВрдЖрдИ рдХреЛ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИред рдШрдЯрдХ рд░рд╛рдЬреНрдп рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ (рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдпрд╛ рддреЛ рдШрдЯрдХ рдореЗрдВ рдпрд╛ рдЙрдЪреНрдЪ рд╕реНрддрд░ рдкрд░ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ, рдЖрдк рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЧ рдлрд╝реАрд▓реНрдб рдкреНрд░рдХрд╛рд░ рдФрд░ рдШрдЯрдХ рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред Mobx рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдо рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд▓рд┐рдП рд▓рдЧрднрдЧ рдЕрдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХреЛрдВ рдХреЛ рдбреЗрдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдВред

Source: https://habr.com/ru/post/hi462597/


All Articles