Π€ΡΠ½ΠΊΡΠΈΡ makeObservable
Π΄Π΅Π»Π°Π΅Ρ ΠΊΠ»Π°ΡΡ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡΠΌ. Π€ΡΠ½ΠΊΡΠΈΡ makeAutoObservable
Π΄Π΅Π»Π°Π΅Ρ ΠΊΠ»Π°ΡΡ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡΠΌ ΠΏΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΠΎΠΌΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΡ ΠΈ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ Π½ΡΠΆΠ½ΡΠ΅ Π΄Π»Ρ Π½Π΅Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ.
ΠΡΠ±Π°Ρ ΡΠΎΠ·Π΄Π°Π½Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ MobX - ΡΡΠΎ ΡΠΊΡΠ΅Π½, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΠ΅Π½ΡΠ΅Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅. Π ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ Redux, ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΌΡΡΠΈΡΠΎΠ²Π°ΡΡ. Π’ΠΎ Π΅ΡΡΡ, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠΌ ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΡΠΎ MobX ΡΡΠΎ Π·Π°ΠΌΠ΅ΡΠΈΡ ΠΈ Π·Π°ΠΏΡΡΡΠΈΡ ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°.
Π‘Π΅ΠΉΡΠ°Ρ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠ»Π°ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π» Π½Π° ΡΡΡΠ°Π½ΠΈΡΠ΅ (Π² Π²ΠΈΠ΄Π΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²). Π ΠΊΠΎΠ½ΡΠ΅ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈΠ½ΡΡΠ°Π½Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΊΠ»Π°ΡΡΠ°.
State / store / counter.ts
import { makeAutoObservable } from 'mobx';
class Counter {
// ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ
count = 0;
constructor() {
// Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅Ρ ΡΠ°Π±ΠΎΡΡ Ρ mobx
makeAutoObservable(this);
}
increment() {
this.count = this.count + 1;
}
decrement() {
this.count = this.count - 1;
}
}
export default new Counter();
ΠΠ°Π»Π΅Π΅ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ Π½Π°Ρ ΠΊΠ»Π°ΡΡΠΎΠ²ΡΠΉ ΠΊΠ°ΡΠ½ΡΠ΅Ρ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ ΠΈ Π²ΡΡΠ°Π²ΠΈΡΡ Π΅Π³ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ.
Π’Π΅ΠΏΠ΅ΡΡ, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠ°ΡΠ½ΡΠ΅Ρ Ρ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ, ΠΎΠΏΠΈΡΠ°Π½Π½ΡΠΌΠΈ Π² MobX, Π½ΡΠΆΠ½ΠΎ ΠΎΠ±Π΅ΡΠ½ΡΡΡ Π²Π΅ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ Π² ΡΡΠ½ΠΊΡΠΈΡ observer
, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅ ΠΈ ΠΏΠ΅ΡΠ΅ΡΠ΅Π½Π΄Π΅ΡΠΈΠ²Π°Π΅Ρ Π΅Π³ΠΎ.
State / State.tsx
import React from 'react';
import { useState } from 'react';
import styles from './State.module.scss';
import { Button } from '@/components';
import counter from './store/counter';
import { observer } from 'mobx-react-lite';
export const State = observer((): JSX.Element => {
return (
<div className={styles.wrapper}>
<h2 className={styles.title}>Π‘ΡΡΡΡΠΈΠΊ:</h2>
<h1 className={styles.num}>{counter.count}</h1>
<Button
buttonType={'gray'}
className={styles.reduce}
onClick={() => counter.decrement()}
>
Π£ΠΌΠ΅Π½ΡΡΠΈΡΡ
</Button>
<Button
buttonType={'purple'}
className={styles.increase}
onClick={() => counter.increment()}
>
Π£Π²Π΅Π»ΠΈΡΠΈΡΡ
</Button>
</div>
);
});
Π ΡΠ΅ΠΏΠ΅ΡΡ Π½Π°Ρ ΡΡΡΡΡΠΈΠΊ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΈ Π±ΡΡΡΡΠΎ ΠΎΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π½Π° Π²ΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ
ΠΠ°Π»Π΅Π΅ ΠΏΡΠΈΠ²Π΅Π΄ΡΠΌ Π΅ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΏΡΠΈΠΌΠ΅Ρ, Π³Π΄Π΅ ΠΌΡ ΡΡΠ°Π·Ρ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΄Π°Π½Π½ΡΠ΅ ΠΈ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΡΠΏΠΈΡΠΎΠΊ Π΄Π΅Π»
Todo / store / todo.store.ts
import { makeAutoObservable } from 'mobx';
interface ITodo {
id: number;
title: string;
completed: boolean;
}
class TodoStore {
todos: ITodo[] = [
{ id: 1, title: 'Π‘Ρ
ΠΎΠ΄ΠΈΡΡ Π² ΠΌΠ°Π³Π°Π·ΠΈΠ½', completed: false },
{ id: 2, title: 'ΠΡΠΏΠΈΡΡ Ρ
Π»Π΅Π±', completed: false },
{ id: 3, title: 'Π‘ΡΠ΅ΡΡΡ Ρ
Π»Π΅Π±', completed: false },
];
constructor() {
makeAutoObservable(this);
}
addTodo(todo: ITodo) {
this.todos.push(todo);
}
removeTodo(id: number) {
this.todos = this.todos.filter(todo => todo.id !== id);
}
completeTodo(id: number) {
this.todos = this.todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo,
);
}
}
export default new TodoStore();
Π‘Π΅ΠΉΡΠ°Ρ ΡΠΏΠΈΡΠΎΠΊ Π΄Π΅Π» ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΡΡΡ ΠΏΠΎΡΡΠΈ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ ΠΏΡΠΎΡΠ»ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ Ρ ΠΊΠ°ΡΠ½ΡΠ΅ΡΠΎΠΌ. Π MobX ΠΎΡΠ΅Π½Ρ Π²Π°ΠΆΠ½ΠΎ, ΡΡΠΎΠ±Ρ ΠΊΠ»ΡΡΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π±ΡΠ»ΠΈ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΌΠΈ, ΠΈ ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ Π½Π΅ ΡΠ²Π»ΡΠ»ΠΈΡΡ ΠΈΠ½Π΄Π΅ΠΊΡΠ°ΠΌΠΈ ΠΌΠ°ΡΡΠΈΠ²Π°
TodoList / TodoList.tsx
import React from 'react';
import { observer } from 'mobx-react-lite';
import todo from './store/todo.store';
import styles from './TodoList.module.scss';
import { Button, Input } from '@/components';
export const TodoList = observer(() => {
return (
<div className={styles.wrapper}>
{todo.todos.map(t => (
<div key={t.id} className={styles.todo}>
<Input
type={'checkbox'}
checked={t.completed}
onChange={() => todo.completeTodo(t.id)}
/>
<div>{t.title}</div>
<Button
className={styles.button}
buttonType={'purple'}
onClick={() => todo.removeTodo(t.id)}
>
X
</Button>
</div>
))}
</div>
);
});
Π ΡΠ΅ΠΏΠ΅ΡΡ Π½Π°Ρ ΡΠΏΠΈΡΠΎΠΊ Π΄Π΅Π» ΡΠ΄Π°Π»ΡΠ΅Ρ ΡΠ΅Π±Ρ ΠΈ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π½ΡΠΌ
Π’Π°ΠΊ ΠΆΠ΅ Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ, ΡΡΠΎ Π΅ΡΠ»ΠΈ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ Π±ΠΎΠ»Π΅Π΅ Π³Π»ΡΠ±ΠΎΠΊΠΈΠΌΠΈ ΡΡΠΎΠ²Π½ΡΠΌΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡΠΈ, ΡΡΠΎ Π² ΠΌΠΎΠ± Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΎΠΏΡΠΈΡ deep
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΎΡΠ½ΠΈΡΡ Π²Π½ΡΡΡΠΈ ΠΎΠ²Π΅ΡΡΠ°ΠΉΠ΄Π° (Π²ΡΠΎΡΠΎΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΌΠΎΠ±Π°):
- ΡΡΠΎ Π΅ΡΡΡ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ
todos: observable
, - ΡΡΠΎ Π΅ΡΡΡ ΡΠΊΡΠ΅Π½Ρ
addTodo: action
- Π ΡΡΠΎ ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΡΡΠΈΡΠ»ΡΠ΅ΠΌΡΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ
computed: Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅
constructor() {
makeAutoObservable(this, { todos: observable, addTodo: action, computed: });
}
ΠΡΡΠΈΡΠ»ΡΠ΅ΠΌΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ - ΡΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΡΡΠΈΡΠ°Π΅ΠΌ Π² ΠΌΠ΅ΡΠΎΠ΄Π΅, ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Π½ΠΎΠΌ ΠΊΠ»ΡΡΠ΅Π²ΡΠΌ ΡΠ»ΠΎΠ²ΠΎΠΌ get
. ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΡΡΠΈΡΠ»ΡΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΊΠ°ΠΊΠΈΡ
-ΡΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΉ. ΠΡΠ½ΠΎΠ²Π½ΠΎΠ΅ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²ΠΎ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΌΠ΅ΡΠΎΠ΄ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π΅Π³ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ» ΡΠ²ΠΎΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅. Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΡΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ.
get total() {
return `Counter = ${this.timer + this.count}`;
}
Π’Π΅ΠΏΠ΅ΡΡ ΡΡΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ
<h1 className={styles.num}>{counter.total}</h1>
ΠΡΠΈΠ½Ρ
ΡΠΎΠ½Π½ΡΠ΅ ΡΠΊΡΠ΅Π½Ρ. ΠΠ½ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ ΡΠΎΠ²Π½ΠΎ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠΊΡΠ΅Π½Ρ.
Π’ΡΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΏΠΈΡΠΊΠ° Π΄Π΅Π» Ρ ΡΠ΅ΡΠ²Π΅ΡΠ° jsonplaceholder
todo.store.ts
fetchTodos() {
fetch('https://jsonplaceholder.typicode.com/todos/')
.then(response => response.json())
.then(json => {
this.todos = [...this.todos, ...json];
});
}
Π’ΡΡ ΠΏΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π΄Π°Π½Π½ΡΠΉ ΠΌΠ°ΡΡΠΈΠ²
TodoList.tsx
<Button buttonType={'gray'} onClick={() => todo.fetchTodos()}>
ΠΠΎΠ»ΡΡΠΈΡΡ ΡΠΏΠΈΡΠΎΠΊ Π΄Π΅Π»
</Button>
Π Π²ΠΈΠ΄ΠΈΠΌ ΠΎΠ³ΡΠΎΠΌΠ½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ Π΄Π΅Π»