本文共 5307 字,大约阅读时间需要 17 分钟。
react中的状态管理有很多,我们今天讲的是react-redux 和 mobx。
一:mobx
1、根目录
index.js
import { Provider } from 'mobx-react'
ReactDOM.render(<Provider locale={zh_CN}><App store={AppStore} /></Provider>, document.getElementById('root'))
app.js
import { Provider } from 'mobx-react'render() { //const newState = new AppStore() return () } {/**/}
2、appStore文件
import { observable, computed, action } from 'mobx';
@observable:值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射。其修饰的state会暴露出来供观察者使用
@observable
接受任何类型的 js 值(原始类型、引用、纯对象、类实例、数组和、maps),observable 的属性值在其变化的时候 mobx 会自动追踪并作出响应。
当 value 是一个对象类型值的时候,它会默认克隆该对象并且把其中每个属性变为可观察的值,这里默认是深拷贝,也就是说其对象的后代属性都会变成可观察的,比如 @observable classProperty = { obj: { name: 'q' } }
,当 classProperty.obj.name
改变的时候,在 MobX 中也是可以观察到并响应的;
当然在这里可以加一些调节器来做一些配置:
@action:只有在 actions 中,才可以修改 Mobx 中 state 的值,支持异步
注意:当你使用装饰器模式时,@action 中的 this 没有绑定在当前这个实例上,要用过 @action.bound 来绑定 使得 this 绑定在实例对象上。@computed get TodoListCount() {
return this.todos.length;
}
autorun
在上面的例子中,当触发了可观察状态属性的改变后,其变化的监听则是在传入 autorun 函数中作出响应。
autorun 接受一个函数作为参数,在使用 autorun 的时候,该函数会被立即调用一次,之后当该函数中依赖的可观察状态属性(或者计算属性)发生变化的时候,该函数会被调用,注意,该函数的调用取决的函数中使用了哪些可观察状态属性(或者计算属性)。
componentDidMount() { const { store } = this.props var that = this autorun(() => { console.log('11', store.name) that.setState({ numbers: store.name }) }) }
3、组件中引入:
import { observer, inject } from 'mobx-react'
@inject('store')
@observer
//获取store
const { store } = this.props
store.setWarnFlag(false)
class appStore { @observable socketUrl = 'kc.tianren.com:6060/ws' @action setSocketUrl(socketUrl) { this.socketUrl = parseInt(socketUrl) } @observable nowIndex = 0 @observable childNowIndex = 5 @action setIndex(nowIndex) { this.nowIndex = parseInt(nowIndex) } @action setChildIndex(childNowIndex) { this.childNowIndex = parseInt(childNowIndex) } @observable flag = false @action setFlag(flag) { this.flag = flag } @observable warnFlag = true @action setWarnFlag(warnFlag) { this.warnFlag = warnFlag } @observable todos = [ { name: `李四`, age: 1 } ] //todos列表 @action fetchTodos() { var randomAge = Math.random(10) this.todos.push({ name: `张三${randomAge}`, age: randomAge }) } @action fetchTodoRemove() { this.todos.pop() } //添加 @action AddTodo = () => { this.fetchTodos() } //删除单个 @action remove() { this.fetchTodoRemove() } //计算长度 @computed get TodoListCount() { return this.todos.length }}const AppStore = new appStore()export default AppStore
二:Redux
index.js//import { Provider } from 'react-redux'import { createStore } from 'redux';import testReducer from './store/reducer'const store = createStore(testReducer)Home.js//import { connect } from "react-redux"import { setName, getName, resetName } from '../store/actions'setA(name) { console.log('sss') this.props.setName(name)}function mapStateToProps(state) { return { name: state.name };}const mapDispatchToProps = { setName, getName, resetName};export default connect(mapStateToProps, mapDispatchToProps)(Home)
reduce //import { SET_NAME, GET_NAME, RESET_NAME } from './actions'const finialState = { name: '未设置'};export default function testReducer(state = finialState, actions) { switch (actions.type) { case GET_NAME: return { name: `my name is ${state.name}` } case SET_NAME: return { name: actions.preload.value } case RESET_NAME: return { name: '未设置' } default: return state; }} //rootReducerimport { combineReducers } from "redux";export default combineReducers({ products});
同样注意 Redux 如何传递了一个 undefined 的 state,同时 action 是一个有 type 属性的对象。
我们稍后会更多地讨论 actions。现在,我们先看看 reducer。记住 reducer 的职责是接收当前 state 和一个 action 然后返回新的 state。
const initialState = { count: 0};function reducer(state = initialState, action) { console.log('reducer', state, action); return state;}
Actions 的格式非常自由。只要它是个带有 type 属性的对象就可以了。
另一个关于 reducers 的规则是它们必须是纯函数。也就是说不能修改它们的参数,也不能有副作用(side effect)。必须返回一个 state,不要改变 state
const store = createStore(reducer);
store.dispatch({ type: "INCREMENT" });要做到这一点,要用到 react-redux 库的两样东西:一个名为 Provider 的组件和一个 connect 函数。
function mapStateToProps(state) { return { count: state.count };} export default connect(mapStateToProps)(Counter);
这样写是因为 connect 是一个高阶函数,它简单说就是当你调用它时会返回一个函数。然后调用返回的函数传入一个组件时,它会返回一个新(包装的)组件。
固执的 Redux 只接受简单对象作为 actions。
“thunk” 是(少见)指被其它函数作为返回值的函数。你可以像其他 action 生成器一样 dispatch 这些 “thunk actions”:dispatch(getUser())。
function doStuff() { return function(dispatch, getState) { // 在这里 dispatch actions // 或者获取数据 // 或者该干啥干啥 }}
Action 生成器返回的函数接收两个参数:dispatch 函数和 getState。
大多数场景你只需要 dispatch,但有时你想根据 Redux state 里面的值额外做些事情。这种情况下,调用 getState() 你就会获得整个 state 的值然后按需所取。
export function fetchProducts() { return dispatch => { dispatch(fetchProductsBegin()); return fetch("/products") .then(res => res.json()) .then(json => { dispatch(fetchProductsSuccess(json.products)); return json.products; }) .catch(error => dispatch(fetchProductsFailure(error))); };}
转载地址:http://aemsi.baihongyu.com/