拆分各页面state
在src下创建mobx文件夹
mobx内目录如下
index.js为mobx的入口文件,主要做一些mobx配置等,仓库合并抛出,我在index.js里,用了require.context
方法,读取modules下的js文件,转化为对象抛出。
mobx/index.js
const modelCreator = function () {
const store = {};
const context = require.context('./modules', false, /\.(js|ts)$/);
const modelList = context.keys();
modelList.forEach((model) => {
const newSpaces = model.match(/\/(\w+)\.js$/)[1];
store[newSpaces] = context(model).default;
});
return store;
};
export default modelCreator();
在modules/detail.js
import { observable, action, makeAutoObservable } from 'mobx';
import api from '../../api'; //引入api
import { message } from 'antd'; //全局提示
let { detail } = api; //解构出来detail的api请求
//拆分了UIStore,管理当前页所有的ui数据
class UIStore {
@observable x = 0;
@action setX = () => this.x++;
}
//拆分了DomainStore,管理当前页的数据
class DomainStore {
@observable titleList = [];
@observable essayObj = {};
@action getTitleList = async () => {
let { data } = await detail._getList();
if (data.code === 200) {
this.titleList = data.data;
// message.success(data.msg);
} else {
console.log(data.data);
message.error(data.msg);
}
}
@action getEssayObj = async (obj) => {
let { data } = await detail._getListObj({ params: obj });
if (data.code === 200) {
this.essayObj = data.data;
// message.success(data.msg);
} else {
console.log(data.data);
message.error(data.msg);
}
}
}
//合并UIStore和DomainStore
class Store {
@observable uiStore = new UIStore();
@observable domainStore = new DomainStore();
}
export default makeAutoObservable(new Store());
detail页面使用mobx
import React, { Component } from 'react';
import { inject,observer } from 'mobx-react';
import './detail.scss';
import { BankOutlined } from '@ant-design/icons';
import {Link} from 'react-router-dom';
@inject('detail')
@observer
class Detail extends Component {
state = {
id: "",
leftList: [],
essayObj: {}
}
componentDidMount() {
this.init();
}
async init() {
let id = this.props.location.state?.id?this.props.location.state.id:'1';
let { domainStore } = this.props.detail;
await domainStore.getTitleList();
await domainStore.getEssayObj({id});
let {titleList,essayObj} = domainStore;
this.setState({
id,
essayObj,
leftList: titleList
});
}
changeId = async (id) => {
let { domainStore } = this.props.detail;
await domainStore.getEssayObj({id});
let {essayObj} = domainStore;
this.setState({
id,
essayObj
})
}
render() {
let { id, essayObj, leftList } = this.state;
return (
<div className="detaill">
<div className="detaill_header">
<BankOutlined />
<Link to="/"><span className="navItem">Home</span></Link>/
<span className="navItem">detaill</span>/
<span className="navItem">{id}</span>
</div>
<div className="detaill_main">
<div className="detaill_left">
<div className="detaill_left_top">
目 录
</div>
<div className="detaill_left_certer">
<ul>
{
leftList[0] && leftList.map(item => (
<li
onClick={() => this.changeId(item.id)}
className={item.id === id ? 'active' : ''}
key={item.id}
>
{item.title}
</li>
))
}
</ul>
</div>
<div className="detaill_left_bottom"></div>
</div>
<div className="detaill_center">
{
essayObj.id && (<div ref={c => this.center = c}>
<div className="detaill_main_title">
<div className="title">{essayObj.title}</div>
<div className="type">{essayObj.className}</div>
</div>
<div className="detaill_main_content">
<div className="_html" dangerouslySetInnerHTML={{ __html: essayObj.conText }} />
</div>
<div className="img">
<img src={essayObj.img} alt="" />
</div>
<div className="detaill_main_time">
{essayObj.dataTime}
</div>
</div>)
}
<div className="detaill_main_bottom">
</div>
</div>
<div className="detaill_right">
</div>
</div>
<div className="detaill_footer">
</div>
</div>
)
}
}
export default Detail;
注意注意,最外层引入mobx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './mobx';
import {Provider} from 'mobx-react';
ReactDOM.render(
<Provider {...store}>
<App />
</Provider>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();