使用 MobX (结合 Context)
© 转载需要保留原始链接,未经明确许可,禁止商业使用。支持原创 CC BY-NC-SA 4.0
Class 组件
1. 创建共享的数据源
store.js
import React from 'react';
import { action, computed, makeAutoObservable } from 'mobx';
// 创建Context
const AppContext = React.createContext({});
const { Provider, Consumer } = AppContext;
// 需要共享的数据,可以声明为 Class
class AppState {
constructor() {
// 将当前 Class 变成可观察的
makeAutoObservable(this);
}
staticData = 'static';
data = 'default';
changeData = action((newData) => {
this.data = newData;
});
newData = computed(() => {
return `${this.data}-new`;
});
}
// 包装组件
class AppStore extends React.Component {
render() {
return (
<Provider value={new AppState()} {...this.props}>
{this.props.children}
</Provider>
);
}
}
export { AppStore, AppContext, Consumer };
2. 创建消费者组件
Parent.js
import React, { Component } from 'react';
import { observer } from 'mobx-react';
import { AppContext } from './store';
const Parent = observer(
class ClassComponent extends Component {
static contextType = AppContext;
handleChange = () => {
this.context.changeData('New');
};
render() {
return (
<div>
消费者组件:{this.context.data}
<button onClick={this.handleChange}>Change</button>
</div>
);
}
}
);
export default Parent;
这里使用了
Class.contextType,使用Consumer也是可以的。
3. 将消费者作为包装组件的子组件
index.js
import React from 'react';
import Parent from './Parent';
import { AppStore } from './store';
class MyApp extends React.Component {
render() {
return (
<AppStore {...this.props}>
<Parent {...this.props} />
</AppStore>
);
}
}
export default MyApp;
Function 组件
1. 创建共享的数据源
数据源 (store) 文件中做了 4 部分操作:
- 创建需要共享的数据:这里可以是多样的,一般是声明为
Class - 创建
Context - 自定义
Hook暴露Context:这样是为了更方便的引用。 - 自定义包装组件
store.js
import React from 'react';
import { action, observable } from 'mobx';
// 创建Context
const AppContext = React.createContext({});
const { Provider, Consumer } = AppContext;
// 需要共享的数据
let appState = observable({
data: 'default',
// computed data
get newData() {
return `${appState.data}-new`;
},
// action 触发数据变更
changeData: action((newData) => {
appState.data = newData;
}),
});
// 包装组件
const AppStore = (props) => (
<Provider value={appState} {...props}>
{props.children}
</Provider>
);
// 自定义Hooks
const useStore = () => React.useContext(AppContext);
export { AppStore, Consumer, useStore };
2. 创建消费者组件
Parent.js
import React from 'react';
import { observer } from 'mobx-react';
import { useStore } from './store'; //只需引用自定义的 Hook 即可
const Parent = observer((props) => {
// 调用自定义 Hook 从 Context 取值
const { data, newData, changeData } = useStore();
const handleChange = () => {
changeData('haha');
console.log('store', data);
};
return (
<div>
消费者组件:{data}
{newData}
<button onClick={handleChange}>Change</button>
</div>
);
});
export default Parent;
说明
这里使用 Consumer 好使吗?
自然也是好使的!只不过 Consumer 的方式写法不够简洁罢了!
3. 将消费者作为包装组件的子组件
index.js
import React from 'react';
import Parent from './Parent';
import { AppStore } from './store';
const MyApp = (props) => (
<AppStore {...props}>
<Parent {...props} />
</AppStore>
);
export default MyApp;