前言:redux和mobx都是狀態管理器,避免父級到子級再到子子級嵌套單向數據流,能夠邏輯清晰的管理更新共享數據。(刷新頁面redux儲蓄數據即消失)
配置使用裝飾器(使用高階函數包裝你的組件):
npm install babel-plugin-transform-decorators-legacy --save-dev
.babelrc配置:javascript
{ "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "antd", "style": true } ], "transform-decorators-legacy" ] }
當使用react native的時候,下面這個預設能夠代替 transform-decorators-legacyjava
"babel": { "presets": [ "react-app", "react-native-stage-0/decorator-support" ] },
一.redux
redux.js文件:
// 定義變量 const CODE_CHANGE = 'CODE_CHANGE' const NUMBER_LIST = 'NUMBER_LIST' const ERROR_MSG = 'ERROR_MSG' // 初始化數據 const initState = { industryNumber: storage.get('industryNumber'), numberList: [], msg: '' } // reducer export function isNumber(state = initState, action) { switch (action.type) { case CODE_CHANGE: return { ...state, industryNumber: action.industryNumber } case NUMBER_LIST: return { ...state, numberList: action.numberList } case ERROR_MSG: return { ...state, msg: action.msg } default: return state } }
reducer.js文件:react
import { combineReducers } from 'redux' import { isNumber } from '/redux' export default combineReducers({ isNumber }) // 合併全部的reducer,而且返回
index.js入口文件:git
import React from 'react' import ReactDOM from 'react-dom' import MainRouter from './Router' // 引入redux import { createStore, applyMiddleware, compose } from 'redux' importthunk from 'redux-thunk' // 中間插件,加強dispatch功能,可異步加載action可接受函數參數 import { Provider } from 'react-redux' //redux組件,所有子級能夠直接更新redux的state import reducers from './reducer' // 這裏判斷瀏覽器環境是否開啓Redux DevTools的插件(chrome瀏覽器擴展插件應用商店下載) const reduxDevtools = window.devToolsExtension ? window.devToolsExtension() : h => h //沒有插件則返回空函數 const store = createStore(reducers, compose( applyMiddleware(thunk), reduxDevtools )) // 建立store ReactDOM.render( <Provider store={store}> <MainRouter/> //路由 </Provider>, document.getElementById('root') )
某子組件:github
import { connect } from 'react-redux' // 裝飾器 const fetchNumberList = () => { return dispatch => { // 異步請求須要 dispatch => {}包裹 fetch('異步請求').then(res => { if (res.code === 0) { dispatch({ type: 'NUMBER_LIST', numberList: res.data }) } }) } } @connect( state => state.isNumber, // 若是有多個reducer: state => ({ ..state.isNumber, ...state.someName }) { fetchNumberList } // 一些以前寫好的action方法 ) class IndustryManagement extends Component { constructor(props) { super(props) this.state= { industryNumber: this.props.industryNumber && this.props.industryNumber[0], // 直接props引用redux的state } } btnChange() { this.props.fetchNumberList() //通過裝飾器的函數均可用props引用 } render() { return ( <button onClick={ this.btnChange.bind(this) }> ) } }
二. mobxchrome
這裏推薦使用mobx-state-tree的寫法,有興趣的可去github上看用法,如下是傳統寫法:npm
store.js文件:
import { observable, action, runInAction } from 'mobx' // runInAction接受異步action class RootStore { @observable userInfo = null //註冊變量並監視變化(能夠是引用類型值或者普通值) @observable number1 = 1 @observable number2 = 2 @computed getTotal(){ return this.number1 + this.number2 // 每當監視數據發生變化就會執行@computed } @action.bound getData= async() => { // bound是爲了綁定this上下文(箭頭函數可不須要) let res = await get('接口地址') if (res.success) { runInAction(() => { // runInAction函數可異步修改@observable數據 this.userInfo = res.data }) } } } export default rootStore = new RootStore()
index.js入口文件:redux
import { Provider } from 'mobx-react' // 與上文的redux的Provider類似 import rootStore from './store' ReactDOM.render( <Provider rootStore={rootStore}> <MainRouter /> </Provider>, document.getElementById('root') )
某子組件:react-native
import { observer, inject } from 'mobx-react' @inject(({store, otherStore}) => ({ // 選擇注入store(若是有多個store),若是不用inject函數可直接import store from '../store',組件中直接store.userInfo使用 userInfo: store.userInfo, total: store.getTotal })) @observer class EmpRec extends Component { constructor(props) { super(props) } render() { return( <div> <div>this.props.userInfo</div> <div>this.props.total</div> </div> ) } }
.瀏覽器