→ MobX — это инструмент управления состоянием. Это еще один магазин, похожий на Redux.
→ Код менее сложный, но мощный. Есть три терминологии:
1. Состояние — данные, которые управляют приложением. Состояние магазина MobX.
Мы помечаем свойство как наблюдаемое, и MobX достаточно умен, чтобы знать, когда значение состояния обновляется. Зависимый.
2. Действия — любой фрагмент кода, который изменяет состояние.
3. Вывод — все, что выводится из состояния без какого-либо дальнейшего взаимодействия.
Установка плагина MobX для Chrome:
→ Теперь, как и в Redux, у нас есть расширение для Chrome, где мы можем просматривать данные о состоянии хранилища MobX. Мы будем использовать его в нашем проекте ниже.
Что мы создаем?
→ Приложение Todo, которое извлекает данные из магазина MobX вместо состояния React.
→ Мы выполним операцию CRUD с состоянием MobX.
Установка Реакт JS:
ШАГ 1: Давайте установим приложение React, используя следующую команду:
npx create-react-app –template mobx-react-todo
ШАГ 2: Установите mobx и mobx-react-lite
npm install mobx mobx-react-lite
→ Мы создали внутри компонентов две папки. Мы можем сослаться на полный код здесь.
Файл: src/components/Home.js
import React from 'react'; function Home({ store }) { return ( <div className="App"> <h1>MobX 2</h1> </div> ); } export default Home
→ Теперь создаются два пустых файла — About.js и UserStore.js
→ В UserStore мы напишем полный код MobX (это наш магазин)
Браузер:
→ Следующим шагом будет запись в UserStore.js
Файл: src/UserStore.js
import { action, computed, makeObservable, observable, autorun, runInAction } from 'mobx'; // DEFAULT STATE class UserStore { userInfo = { id: 'C117', name: 'code', subject: ['English', 'CS', 'Maths'] } constructor() { makeObservable(this, { userInfo: observable, totalSubject: computed, updateUser: action, addSubject: action }); autorun(this.logUserDetails); // WILL RUN AFTER EVERY ACTION INVOKE runInAction(this.prefetchData); } // All getters behave as computed i.e. instantly calculate without action get totalSubject() { return this.userInfo.subject.length; } logUserDetails = () => { console.log(`Subject length: ${this.totalSubject()}`); } updateUser = (name) => { return 'NA'; } addSubject = (data) => { return 'NA'; } prefetchData = () => { console.log('printing prefetchData...'); } } export default UserStore;
Файл: src/App.js
import './App.css'; import Home from './components/Home'; import UserStore from './UserStore'; function App() { const store = new UserStore(); return ( <Home store={store} /> ); } export default App;
→ Теперь, чтобы использовать хранилище в компоненте, мы будем использовать библиотеку mobx-react-lite.
Файл: src/components/Home.js
import React from 'react'; import { observer } from "mobx-react-lite" function Home({ store }) { return ( <div className="App"> <h1>MobX Store</h1> <h1>{store.userInfo.name} - {store.userInfo.id}</h1> </div> ); } export default observer(Home);
→ Ура, мы получили данные нашего первого магазина, то есть имя и идентификатор userInfo 😀
Порядок, в котором консоли печатают:
1-й — все геттеры в магазине MobX будут печатать
2-й — запускается autorun()
3-й — runInAction запускается
Файл: src/UserStore.js
import { action, computed, makeObservable, observable, autorun, runInAction } from 'mobx'; class UserStore { userInfo = { id: '113', name: 'Happy Learnings', subject: ['English', 'CS', 'Maths'] } constructor() { makeObservable(this, { userInfo: observable, totalSubject: computed, updateUser: action, addSubject: action }); autorun(this.logUserDetails); runInAction(this.prefetchData); } get totalSubject() { console.log(`getter`); // ADDED CONSOLE return this.userInfo.subject.length; } logUserDetails = () => { console.log(`Subject length: ${this.totalSubject}`); // ADDED CONSOLE } updateUser = (name) => { return 'NA'; } addSubject = (data) => { return 'NA'; } prefetchData = () => { console.log('run in action...'); // ADDED CONSOLE } } export default UserStore;
Браузер:
→ Наблюдаем сначала отпечатки геттеров, затем автозапуск и, наконец, runInAction
Обновление состояния MobX:
→ Давайте создадим кнопку для обновления состояния.
→ Для любого состояния, которое нам нужно обновить, мы должны пройти маршрут действия.
→ Мы создадим кнопку и будем использовать этот метод хранения для обновления состояния.
Файл: src/UserStore.js
import { action, computed, makeObservable, observable, autorun, runInAction } from 'mobx'; class UserStore { userInfo = { id: '113', name: 'Happy Learnings', subject: ['English', 'CS', 'Maths'] } // NOTE: MakeObservable, autorun and runInAction are written in constructor constructor() { makeObservable(this, { userInfo: observable, totalSubject: computed, updateUser: action, // MOBX SHOULD KNOW - UPDATE STATE addSubject: action }); autorun(this.logUserDetails); runInAction(this.prefetchData); } get totalSubject() { console.log(`getter`); return this.userInfo.subject.length; } logUserDetails = () => { console.log(`Subject length: ${this.totalSubject}`); } updateUser = (name) => { this.userInfo.name = name; // UPDATE STATE CODE } addSubject = (data) => { return 'NA'; } prefetchData = () => { console.log('run in action...'); } } export default UserStore;
→ Давайте теперь создадим кнопку внутри компонента Home, чтобы обновить это состояние.
Файл: src/components/Home.js
import React from 'react'; import { observer } from "mobx-react-lite" function Home({ store }) { const changeUser = () => { // FUNCTION CREATE store.updateUser("New data"); // USING STORE METHOD TO UPDATE } return ( <div className="App"> <h1>MobX Store</h1> <h1>{store.userInfo.name} - {store.userInfo.id}</h1> <button onClick={changeUser}>Update User</button> </div> ); // ABOVE BUTTON CREATED TO UPDATE STATE } export default observer(Home);
→ Весь код написан в компоненте Home, важно, что мы передаем магазин из приложения
→ Наблюдаем сверху код Home получает магазин.
Файл: src/App.js
import './App.css'; import Home from './components/Home'; import UserStore from './UserStore'; // FETCHING USER STORE function App() { const store = new UserStore(); // INSTANCE IS PASSED IN HOME return ( <> <Home store={store} /> // PASSING STORE to HOME </> ); } export default App;
ПРИМЕЧАНИЕ:
В MobX экземпляр Store передается компонентам
Браузер:
→ Мы видим, что имя изменилось.
→ Теперь давайте добавим темы и на главной странице прокрутим темы.
Файл: src/components/Home.js
import React from 'react'; import { observer } from "mobx-react-lite" function Home({ store }) { const changeUser = () => { store.updateUser("New data"); } const addSubject = () => { // ADD SUBJECT METHOD store.addSubject('Aeronotics'); } return ( <div className="App"> <h1>MobX Store</h1> <h1>{store.userInfo.name} - {store.userInfo.id}</h1> <button onClick={changeUser}>Update User</button> <button onClick={addSubject}>Add Subject</button> { // LOOPING SBJECTS ARRAY PRINING HERE, ADD SUB BUTTON CREATED store.userInfo.subject.map((key, index) => <p key={index}>{key}</p>) } </div> ); } export default observer(Home);
→ В магазине этот метод протолкнет массив
Файл: src/UserStore.js
Примечание. Любая функция, которую мы хотим создать, должна выполняться только в классе Store.
import { action, computed, makeObservable, observable, autorun, runInAction } from 'mobx'; class UserStore { userInfo = { id: '113', name: 'Happy Learnings', subject: ['English', 'CS', 'Maths'] // SUBJECT ARRAY } constructor() { makeObservable(this, { userInfo: observable, totalSubject: computed, updateUser: action, addSubject: action // REGISTER IN MOBX }); autorun(this.logUserDetails); runInAction(this.prefetchData); } get totalSubject() { console.log(`getter`); return this.userInfo.subject.length; } logUserDetails = () => { console.log(`Subject length: ${this.totalSubject}`); } updateUser = (name) => { this.userInfo.name = name; } addSubject = (data) => { // METHOD TO PUSH IN SUBJECT ARRAY this.userInfo.subject.push(data); } prefetchData = () => { console.log('run in action...'); } } export default UserStore;
→ Теперь мы параллельно проверим хранилище Chrome MobX, чтобы наблюдать за состоянием.
→ Откройте инструмент разработчика в Chrome. Так же, как сеть и консоль, также есть MobX (исходит из расширения Chrome, которое мы установили выше).
→ При нажатии кнопки «Обновить пользователя» вызывается метод updateUser в классе.
→ Мы видим, что MobX обнаружил данные. Мы можем увидеть последнюю стоимость магазина здесь.
→ Теперь давайте нажмем кнопку «Добавить тему» — в настоящее время она жестко закодирована (Aeronotics).
Файл: src/components/Home.js (как мы видели в коде выше)
const addSubject = () => { store.addSubject('Aeronotics'); }
→ Нажмите Добавить тему
→ Мы наблюдаем обнаруженные изменения состояния хранилища MobX. Нажмите на addSubject на MobX
→ Мы видим, что Aeronautics добавляется в массив магазина
→ Это также отображается в браузере, как показано выше.
Примечание: одна интересная вещь:
Мы наблюдаем, что журналы в браузере печатаются, когда вызывается addSubject, а не updateUser для этого.
Файл: src/UserStore.js
import { action, computed, makeObservable, observable, autorun, runInAction } from 'mobx'; class UserStore { userInfo = { id: '113', name: 'Happy Learnings', subject: ['English', 'CS', 'Maths'] } constructor() { makeObservable(this, { userInfo: observable, totalSubject: computed, updateUser: action, addSubject: action }); autorun(this.logUserDetails); runInAction(this.prefetchData); } get totalSubject() { console.log(`getter`); return this.userInfo.subject.length; } logUserDetails = () => { // Added Name in the Log. SO will this method will also invoke in name change console.log(`Subject length: ${this.totalSubject}, Name: ${this.userInfo.name}`); } … … } export default UserStore;
Переход в один и тот же магазин более чем к одному компоненту:
→ Давайте теперь напишем код в файле About.js
Путь: Путь: src/components/About.js (новый компонент)
import { observer } from "mobx-react-lite"; function About({ store }) { // RECEIVES STORE FROM APP FILE return ( <div className="App"> <h1>About - {store.userInfo.name}</h1> </div> ); } export default observer(About);
Файл: src/App.js
import './App.css'; import Home from './components/Home'; import About from './components/About'; import UserStore from './UserStore'; function App() { const store = new UserStore(); return ( <> <Home store={store} /> <About store={store} /> PASSING STORE IN ABOUT COMPONENT </> ); } export default App;
Гитхаб:
https://github.com/AmirMustafa/react-mobx-todo/tree/mobx
Видео:
Заключительные мысли:
В этой статье мы реализовали магазин MobX с помощью приложения React.js. MobX — это управление состоянием, как и Redux.
MobX можно использовать с тяжелыми проектами. Сложность написания кода MobX намного меньше по сравнению с магазином Redux, и процесс выполняется быстро.
Спасибо, что дочитали до конца 🙌 . Если вам понравилась эта статья или вы узнали что-то новое, поддержите меня, нажав кнопку Поделиться ниже, чтобы охватить больше людей, и/или подпишитесь на Twitter и подпишитесь на Happy Learnings !! чтобы увидеть некоторые другие советы, статьи и вещи, о которых я узнаю и делюсь там.