在vue中,可以使用vuex进行数据管理,在react中,可以使用redux进行数据管理。redux主要由Store、Reducer和Action组成:
- Store:状态载体,访问状态、提交状态、监听状态变更
- Reducer:状态更新具体执行者,纯函数
- Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作
简单使用
在redux中,首先需要了解的是store,所有的数据都在这一个数据源里面进行管理,具有全局唯一性,但是redux本身和react并没有直接的联系,可以单独使用,复杂的项目才需要redux来管理数据,简单的项目,state+props+context就足够了。
例如,我们想要实现一个简单的累加器,就需要以下几步:
- 用来存储数据的store,store里面的state是数据放置的位置
- 通过dispatch一个action来提交对数据的修改
- 请求提交到reducer函数里,根据传入的action和state,返回新的state
首先新建项目,然后执行命令npm install redux --save安装redux。
其次,在src文件夹下面新建store.js,创建store,然后根据action的不同类型,执行不同的操作:
store.js
import {createStore} from 'redux'; const counterReducer = (state = 0, action) => { switch(action.type){ case 'add': return state + 1; case 'minus': return state - 1; default: return state; } } export default createStore(counterReducer)
然后在components文件夹下面新建Test.js组件,并在组件中引入store.js
Test.js
import React, {Component} from 'react' import store from '../store' class Test extends Component{ render(){ return ( <div> <p>{store.getState()}</p> <button onClick={()=>store.dispatch({type:'add'})}> + </button> <button onClick={()=>store.dispatch({type:'minus'})}> - </button> </div> ) } } export default Test;
最后使用组件,使用组件分两步:初始化渲染时,需要请求初始化的数据;后面每次数据改变时,重新加载数据。
index.js
// 初始化执行 ReactDOM.render(<Test />, document.getElementById('root')); // 每次发生变化时执行 store.subscribe(()=>{ ReactDOM.render(<Test />, document.getElementById('root')); })
react-redux
如果在大型项目中,我们每次都在需要使用的地方重新调用render,会十分麻烦,所以,需要使用更简洁的方法:react-redux,react-redux提供了两个api:提供数据的顶级组件Provider和提供数据与方法的高阶组件connect。
首先,要实现react-redux,需要先进行安装:npm install react-redux --save
其次,既然要用到高阶组件,就需要使用高阶组件装饰器:npm install --save-dev babel-plugin-transform-decorators-legacy,具体的可以参考前面的react高阶组件。
最后,来改写上面的累加器组件。
1,在index.js中引入Provider组件,并进行相应的修改,这样,后面就不需要再每个需要的页面多次引入store.js了,更不用在每次操作了数据以后重新render。
index.js
import store from './store'; import Test from './components/Test'; import {Provider} from 'react-redux' ReactDOM.render(( <Provider store={store}> <Test /> </Provider> ), document.getElementById('root')); serviceWorker.unregister();
2,在Test.js页面,重新更改写法,使用高阶组件connect来提供数据和方法:
import React, {Component} from 'react' import { connect } from "react-redux"; @connect( state => ({ num: state }), // 状态映射 { add: () => ({ type: "add" }), minus: () => ({ type: "minus" }) } ) class Test extends Component{ render(){ return ( <div> <p>{this.props.num}</p> <button onClick={()=>this.props.add()}> + </button> <button onClick={()=>this.props.minus()}> - </button> </div> ) } } export default Test;
代码下载:点这里