MobX is for state management, simple and efficient. This article on React explains how to get started, including:
- Understand MobX concepts
- Prepare the React application from zero
- MobX React. FC
- MobX React.Com ponent of writing
Ikuoku.github. IO /start-react: github.com/ikuokuo/sta… .
concept
First, the UI is generated by state via fn:
ui = fn(state)
Copy the code
In React, fn, the component, renders according to its state.
What if state is shared, one state update, multiple component responses? This is where MobX comes in.
MobX data flows as follows:
UI relentless action → stateCopy the code
The UI triggers action, updates the state, and redraws the UI. Notice it’s one way.
To learn more, read MobX Themes. Here are the main steps of implementation:
- Define the data store class
Data Store
- The member attributes are
state
, the member function isaction
- with
mobx
Marked asobservable
- The member attributes are
- define
Stores Provider
- Methods a
React.Context
:createContext
packagingStore
Instance,ui
useContext
use - Way 2
mobx-react.Provider
: Direct packagingStore
Instance, provided toProvider
.ui
inject
use
- Methods a
- implementation
ui
component- with
mobx
Marked asobserver
- To obtain
stores
, direct referencestate
- If you want to update
state
, indirect callaction
- with
The project structure is multiple stores directory, define state action of various stores, asynchronous operation is also very simple. To learn more, read:
- Defining a data store
- Asynchronous actions
To prepare
React App
yarn create react-app start-react --template typescript
cd start-react
Copy the code
React Router
Routing library to navigate the sample.
yarn add react-router-dom
Copy the code
Antd
Component library for laying out the UI.
yarn add antd @ant-design/icons
Copy the code
Advanced configuration,
yarn add @craco/craco -D
yarn add craco-less
Copy the code
Craco.config.js is configured with a dark theme:
const path = require('path');
const CracoLessPlugin = require('craco-less');
const { getThemeVariables } = require('antd/dist/theme');
module.exports = {
plugins: [{plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: getThemeVariables({
dark: true.// compact: true,
}),
javascriptEnabled: true,},},},},],webpack: {
alias: { The '@': path.resolve(__dirname, './src')}}};Copy the code
ESLint
VSCode installs the ESLint Prettier extension. Initializing ESLint:
$NPX eslint -init ➤ How would you like to use eslint? DE style ✔ Whattypeof modules does your project use? · EsM ➤ Which framework does your project use? Re-configure your project use TypeScript? · No/Yes ✔ Where does your code run? · Browser ➤ How would you like to define a styleforyour project? ➤ Come to a good foregrounddo you want to follow? · airbnb
✔ What format do you want your config file to be in? JavaScript,Copy the code
To configure.eslintrc.js.eslintignore.vscode /settings.json, see the code. Add to package.json:
"scripts": {
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --ignore-pattern node_modules/"
},
Copy the code
Run yarn Lint. Yarn start Runs.
At this point, the React Antd application is ready. The initial template is as follows, with the first commit visible:
MobX
yarn add mobx mobx-react
Copy the code
Mobx-react includes mobx-React-Lite, so you don’t need to install it.
- If only React.FC (HOOK) is used
mobx-react-lite
Can. - If React.Component (Class) is used
mobx-react
To just go.
Mobx – react – lite and react. FC
Define the Data Stores
makeAutoObservable
After defining the data store model, just call makeAutoObservable(this) in the constructor.
stores/Counter.ts
:
import { makeAutoObservable } from 'mobx';
class Counter {
count = 0;
constructor() {
makeAutoObservable(this);
}
increase() {
this.count += 1;
}
decrease() {
this.count -= 1; }}export default Counter;
Copy the code
React.Context Stores
React.Context can easily pass Stores.
stores/index.ts
:
import React from 'react';
import Counter from './Counter';
import Themes from './Themes';
const stores = React.createContext({
counter: new Counter(),
themes: new Themes(),
});
export default stores;
Copy the code
Create a useStores Hook to simplify the call.
hooks/useStores.ts
:
import React from 'react';
import stores from '.. /stores';
const useStores = () = > React.useContext(stores);
export default useStores;
Copy the code
Pane components, using Stores
Components are wrapped in observers and useStores reference stores.
Pane.tsx
:
import React from 'react';
import { Row, Col, Button, Select } from 'antd';
import { PlusOutlined, MinusOutlined } from '@ant-design/icons';
import { observer } from 'mobx-react-lite';
import useStores from './hooks/useStores';
typePaneProps = React.HTMLProps<HTMLDivElement> & { name? :string;
}
const Pane: React.FC<PaneProps> = ({ name, ... props }) = > {
const stores = useStores();
return (
<div {. props} >
{name && <h2>{name}</h2>}
<Row align="middle">
<Col span="4">Count</Col>
<Col span="4">{stores.counter.count}</Col>
<Col>
<Button
type="text"
icon={<PlusOutlined />}
onClick={() => stores.counter.increase()}
/>
<Button
type="text"
icon={<MinusOutlined />}
onClick={() => stores.counter.decrease()}
/>
</Col>
</Row>{/ *... * /}</div>
);
};
Pane.defaultProps = { name: undefined };
export default observer(Pane);
Copy the code
Mobx – ponent react with React.Com
Define the Data Stores
makeObservable + decorators
Decorators were dropped in MobX 6, but can still be used.
First, enable the decorator syntax. TypeScript is enabled in tsconfig.json:
"experimentalDecorators": true."useDefineForClassFields": true.Copy the code
After defining the data store model, call makeObservable(this) in the constructor. Not required before MobX 6, but now required for decorator compatibility.
stores/Counter.ts
:
import { makeObservable, observable, action } from 'mobx';
class Counter {
@observable count = 0;
constructor() {
makeObservable(this);
}
@action
increase() {
this.count += 1;
}
@action
decrease() {
this.count -= 1; }}export default Counter;
Copy the code
Root Stores
Combine multiple Stores.
stores/index.ts
:
import Counter from './Counter';
import Themes from './Themes';
export interface Stores {
counter: Counter;
themes: Themes;
}
const stores : Stores = {
counter: new Counter(),
themes: new Themes(),
};
export default stores;
Copy the code
Parent component that provides Stores
The parent component adds mox-react. Provider and the property extends stores.
index.tsx
:
import React from 'react';
import { Provider } from 'mobx-react';
import stores from './stores';
import Pane from './Pane';
const MobXCLS: React.FC = () = > (
<div>
<Provider {. stores} >
<h1>MobX with React.Component</h1>
<div style={{ display: 'flex' }}>
<Pane name="Pane 1" style={{ flex: 'auto' }} />
<Pane name="Pane 2" style={{ flex: 'auto' }} />
</div>
</Provider>
</div>
);
export default MobXCLS;
Copy the code
Pane components that inject Stores
Components are decorated with Observers while injecting stores.
Pane.tsx
:
import React from 'react';
import { Row, Col, Button, Select } from 'antd';
import { PlusOutlined, MinusOutlined } from '@ant-design/icons';
import { observer, inject } from 'mobx-react';
import { Stores } from './stores';
typePaneProps = React.HTMLProps<HTMLDivElement> & { name? :string;
};
@inject('counter'.'themes')
@observer
class Pane extends React.Component<PaneProps.unknown> {
get injected() {
return this.props as (PaneProps & Stores);
}
render() {
const{ name, ... props } =this.props;
const { counter, themes } = this.injected;
return (
<div {. props} >
{name && <h2>{name}</h2>}
<Row align="middle">
<Col span="4">Count</Col>
<Col span="4">{counter.count}</Col>
<Col>
<Button
type="text"
icon={<PlusOutlined />}
onClick={() => counter.increase()}
/>
<Button
type="text"
icon={<MinusOutlined />}
onClick={() => counter.decrease()}
/>
</Col>
</Row>
<Row align="middle">
<Col span="4">Theme</Col>
<Col span="4">{themes.currentTheme}</Col>
<Col>
<Select
style={{ width: '60px'}}value={themes.currentTheme}
showArrow={false}
onSelect={(v)= > themes.setTheme(v)}
>
{themes.themes.map((t) => (
<Select.Option key={t} value={t}>
{t}
</Select.Option>
))}
</Select>
</Col>
</Row>
</div>); }}export default Pane;
Copy the code
The last
You can browse through the MobX documentation to see what’s there. Other core concepts not covered are Computeds and Reactions.
React integration, React Optimization, MobX and React integration
GoCoding personal practice experience sharing, please pay attention to the public account!