redux-mobx
├── README.md
├── mobx-demo
│ ├── README.md
│ ├── config-overrides.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── compments
│ │ ├── compnentA.js
│ │ └── compnentB.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── pages
│ │ ├── bar.js
│ │ └── foo.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ └── store
│ ├── index.js
│ └── storeone.js
├── package-lock.json
└── redux-demo
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
├── App.css
├── App.js
├── App.test.js
├── compments
│ ├── compnentA.js
│ └── compnentB.js
├── index.css
├── index.js
├── logo.svg
├── pages
│ ├── bar.js
│ └── foo.js
├── reportWebVitals.js
├── setupTests.js
└── store
├── index.js
└── reducer.js
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
import ‘./index.css‘;
import reportWebVitals from ‘./reportWebVitals‘;
import App from ‘./App‘;
// 添加代码如下
import Foo from ‘./pages/foo‘;
import Bar from ‘./pages/bar‘;
import {HashRouter, Route, Switch } from ‘react-router-dom‘
import {Provider} from ‘react-redux‘;
import store from ‘./store/index‘
ReactDOM.render(
<Provider store = {store}>
<React.StrictMode>
<h1>redux-demo</h1>
<HashRouter>
<Switch>
<Route exact path="/foo" component={Foo}/>
<Route exact path="/bar" component={Bar}/>
<Route exact path="/" component={App} />
</Switch>
</HashRouter>
</React.StrictMode>
</Provider>,
document.getElementById(‘root‘)
);
reportWebVitals();
引入页面Foo, Bar,路由 react-router-dom插件,以及状态管理 react-redux。状态统一管理 store/index.js,这里统一管理store。
通过Provider 传入 store,包裹所有组件,这样组件内部能拿到store数据。
注意
这里的 Switch组件,当匹配到一个路由的时候,就不用往下匹配,这个也是项目优化的一个部分。
store
├── index.js
└── reducer.js
index.js
我这里演示的是一个reducer,如果是多个reducer 可以用 combineReducers 进行合并
import { createStore } from ‘redux‘;
import reducer from ‘./reducer‘;
export default createStore(reducer)
定义简单的action
reducer.js
const defaultState = {
count: 1,
pageName: "default page"
}
const Store = (state = defaultState, action) => {
switch(action.type) {
case ‘COUNT_ADD‘:
state.count += action.value;
break;
case ‘COUNT_SUB‘:
state.count -= action.value;
break;
case ‘COUNT_MUTIL‘:
state.count *= action.value;
break;
default:
state.count = defaultState.count;
}
return {
...state
}
}
export default Store
import React from ‘react‘;
import { connect } from ‘react-redux‘;
// 组件B中获取count的值
function Bar(props) {
const { count, pageName} = props
return <div>
<h2>Bar</h2>
<p>count: {count}</p>
<p>pageName: {pageName}</p>
</div>
}
const BarPage = connect(state => (
state
))(Bar)
export default BarPage;
使用redux中 connect 将组件和store链接起来。connect 一共四个参数,可以看这个文章connect,这个组件里 我们只用里第一个参数,将store 中的值 传递给组件,这样 Bar 函数组件props里面就有我们传进来的数据。
import React, {useState, useEffect} from ‘react‘;
import { connect } from ‘react-redux‘
// 组件B中获取count的值
// http://localhost:4000/get/alluser 接口地址
const Foo = (props) => {
const { count } = props
const [ allData, setAllData ] = useState([]);
useEffect(()=>{
fetch("http://localhost:4000/get/alluser").then(res => {
res.json().then(data => {
setAllData(data.users)
})
})
},[])
return <div>
<h2>Foo</h2>
<p>count: {count}</p>
<ul>
{allData.map((item,index)=>{
return <li key={index}>
<p>{item.name}</p>
<img src={item.avatar_url} width="180"/>
</li>
})}
</ul>
</div>
}
const FooPage = connect(state => (
{
count: state.count
}
))(Foo)
export default FooPage
注意
注意,重点
import React from ‘react‘;
import { connect } from ‘react-redux‘
import { Link } from ‘react-router-dom‘
const CompnentA = (props) => {
// const [count, SetCount] = useState(props.count)
const addCount = () => {
const { changeCount } = props;
changeCount({
type: "COUNT_ADD",
value: 3,
})
}
const subCount = () => {
const { changeCount } = props;
changeCount({
type: "COUNT_SUB",
value: 1,
})
}
const mutilCountfun = () => {
const {mutilCount} = props;
mutilCount({
type: ‘COUNT_MUTIL‘,
value: 10
})
}
return <div>
<h2>组件A</h2>
<p><button onClick={addCount}>count +3</button></p>
<p><button onClick={subCount}>count -1</button></p>
<p><button onClick={mutilCountfun}>count * 10</button></p>
<ul>
<li><Link to="/foo">Foo 页面</Link></li>
<li><Link to="/bar">Bar 页面</Link></li>
<li><Link to="/">APP 主页面</Link></li>
</ul>
</div>
}
const Compnent = connect(null, dispatch => ({
changeCount: ({type, value}) => dispatch({
type,
value,
}),
mutilCount: ({type, value}) => dispatch({
type,
value
})
}))(CompnentA)
export default Compnent
connect 第一个参数,因为不需要,我们没有传store进组件,第二个函数参数mapDispatchToProps,我们传递了一些action方法进去,这些方法会绑定到组件当中。
我们知道我们不能直接修改store 里面的数据,我们需要通过派发器(dispatch)派发一个动作(action),这也是唯一修改state的方法,
这个action方法会触发我们的reducer方法 ,根据对应的action,返回对应的state。
通过上面 componentA的操作,我们已经修改了state 值,在componentB 中就体现出来了,代码如下
import React from ‘react‘;
import { connect } from ‘react-redux‘
// 组件B中获取count的值
function CompnentB(props) {
const { count } = props
return <div>
<h2>组件B</h2>
<p>count: {count}</p>
</div>
}
const CompnentBB = connect(state => (
{
count: state.count
}
))(CompnentB)
export default CompnentBB
整体效果,图片如下
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
import ‘./index.css‘;
import reportWebVitals from ‘./reportWebVitals‘;
import App from ‘./App‘;
import Foo from ‘./pages/foo‘;
import Bar from ‘./pages/bar‘;
import { configure } from "mobx";
import { Provider } from "mobx-react";
import store from ‘./store/index‘
import {HashRouter, Route, Switch } from ‘react-router-dom‘
configure({ enforceActions: "observed" });
ReactDOM.render(
<Provider store = {store}>
<React.StrictMode>
<h1>mobx-demo</h1>
<HashRouter>
<Switch>
<Route exact path="/foo" component={Foo}/>
<Route exact path="/bar" component={Bar}/>
<Route exact path="/" component={App} />
</Switch>
</HashRouter>
</React.StrictMode>
</Provider>,
document.getElementById(‘root‘)
);
reportWebVitals();
这里主要是将redux 的Provider 替换成 mobx的Provider
store
├── index.js
└── storeone.js
import StoreOne from "./storeone";
class Store {
constructor() {
this.storeOne = StoreOne;
}
}
export default new Store();
import { observable, action, makeObservable } from ‘mobx‘;
class appStore {
constructor() {
// 添加makeObservable mobx6.0 状态数据已经修改,但是页面没有更新,需要通过这个方法来强制更新数据
makeObservable(this)
}
// state
@observable count = 1;
@observable pageName = "default pageName";
// getter
get skinWindow() {
return {
};
}
// action
@action
addCount(payload) {
this.count += payload;
}
@action
subCount(payload) {
this.count -= payload;
}
@action
mutilCountfun(payload) {
this.count *= payload;
}
}
const as = new appStore();
export default as
import React from ‘react‘;
import { Link } from ‘react-router-dom‘
import { observer, inject } from ‘mobx-react‘;
const CompnentA = (props) => {
const {storeOne} = props.store
const addCount = () => {
storeOne.addCount(3)
}
const subCount = () => {
storeOne.subCount(1)
}
const mutilCountfun = () => {
storeOne.mutilCountfun(10)
}
return <div>
<h2>组件A</h2>
<p><button onClick={addCount}>count +3</button></p>
<p><button onClick={subCount}>count -1</button></p>
<p><button onClick={mutilCountfun}>count * 10</button></p>
<ul>
<li><Link to="/foo">Foo 页面</Link></li>
<li><Link to="/bar">Bar 页面</Link></li>
<li><Link to="/">APP 主页面</Link></li>
</ul>
</div>
}
export default inject(‘store‘)(observer(CompnentA));
inject(‘store‘)(observer(CompnentA)) => 可以理解为将store 注入 可监测的 CompnentA 中。
点击事件方法 addCount 它会触发 store 里面的 action 方法,
addCount(payload) {
this.count += payload;
}
action 方法 修改 state上的数据,页面上的数据会及时刷新。
从这里我们就可以明显看出与redux的不同,不需要通过reducer 去根据不同的type 来修改state 上的数据,而是直接通过action方法直接修改。
export default inject(‘store‘)(observer(Bar)); => 可以理解为将store 注入 可监测的 页面 Bar 中。
import React from ‘react‘;
import { inject, observer } from ‘mobx-react‘;
// 组件B中获取count的值
function Bar(props) {
const { count, pageName} = props.store.storeOne
return <div>
<h2>Bar</h2>
<p>count: {count}</p>
<p>pageName: {pageName}</p>
</div>
}
export default inject(‘store‘)(observer(Bar));
"scripts": {
"start": "PORT=8000 react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
npm install customize-cra react-app-rewired @babel/plugin-proposal-decorators --save
const{override,addDecoratorsLegacy}=require(‘customize-cra‘);
module.exports=override(addDecoratorsLegacy());
整体效果图片,如下
上面的演示代码已上传 [github] (https://github.com/adouwt/redux-mobx), 如有错误,敬请指出,如需转载清说明出处。感谢阅读??
原文:https://www.cnblogs.com/adouwt/p/14742503.html