在使用 React 過程中使用狀態管理的選擇實在是太多,這裡只找這三種嘗試對比
React ReduxMobxdvaReact Redux❝
官網
❞
單項資料流管理需要下載依賴
yarn add redux react-redux redux-thunk
Provider
透過 Provider 元件來包裹 app 可以使得全域性來訪問我們的 store
import { Provider } from 'react-redux'import store from './store'...ReactDOM.render( <Provider store={store}> <App /> </Provider>, rootElement)
connectconnect 連線元件和狀態管理
import { connect } from 'react-redux'import { addCount } from './store/redux'// ReduxDemo 元件const mapStateToProps = state => { return { num: state.num.count }}const mapDispatchToProps = dispatch => ({ add() { dispatch(addCount()) }})export default connect(mapStateToProps, mapDispatchToProps)(ReduxDemo)
store 套路定義常量定義 actions編寫 reducer建立 store
import { createStore, compose, applyMiddleware, combineReducers } from 'redux'import thunk from 'redux-thunk'const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;// 常量export const ADD = 'demo/add_conut'// actionsexport const changeCount = ({count}) => ({ count, type: ADD})export const addCount = () => { return (dispatch, getState) => { let _state = getState() _state.num.count++; dispatch(changeCount(_state.num)) }}// reducerconst defaultState = { count: 0}const reducer = (state = defaultState, action) => { switch (action.type) { case ADD: return Object.assign({}, state, { count: action.count }); default: return state; }}// storeexport default createStore( // 模組化 reducer combineReducers({ num: reducer // store 中可以定義不同模組 }), composeEnhancers( applyMiddleware(thunk) ));
Mobx❝
文件
❞
雙向資料流繫結安裝依賴
yarn add mobx mobx-react
Mobx 建立 store 相對簡單
store 的不同的方式物件方式import {observable, action, computed, makeAutoObservable, makeObservable } from 'mobx';// 物件const store = makeObservable( { count: 0, get double() { return this.count * 2; }, addCount() { this.count += 1; }, subCount() { this.count -= 1; } }, // 對屬性進行包裝,用於標記屬性的作用 { count: observable, // 響應屬性 double: computed, // 計算屬性 addCount: action, // action 方法,改變響應屬性 subCount: action })export default store
makeObservable 可以建立一個響應式物件,與 Vue 3.0 類似,傳入的物件屬性也是透過 Proxy 代理makeAutoObservable 則更強大,可以自動為物件屬性包裝函式
import { makeAutoObservable } from 'mobx';// 物件const store = makeAutoObservable( { count: 0, get double() { return this.count * 2; }, addCount() { this.count += 1; }, subCount() { this.count -= 1; } })
類方式class Store { constructor() { makeAutoObservable(this) } count = 0 get double() { return this.count * 2; } addCount() { this.count += 1; } subCount() { this.count -= 1; }}export default new Store()
注入 store 與連線元件
在 App.js 中注入 store
import { Provider } from 'mobx-react'import store from './store/mobx';import Mobx from './Mobx.jsx';const App = () => { return ( <div> <Provider store={store}> <Mobx /> </Provider> </div> )}
這裡的 Provider 元件中的 props 為 store,它是可以任由我們自定義的,而在元件中連線需要傳入這個 props 變數名
import { inject, observer } from 'mobx-react'function MobxDemo({store}) { return ( <div> <h2>Mobx</h2> <p>點選數:{store.count}</p> <p>計算屬性雙數:{store.double}</p> <button onClick={() => store.addCount()}>點選 +</button> <button onClick={() => store.subCount()}>點選 -</button> </div> )}export default inject('store')(observer(MobxDemo));
元件透過 inject 注入我們需要傳入的 store,元件透過 props.store 屬性訪問
dva❝
文件
❞
dva 是一個的 React 應用框架,簡化 API,讓開發 React 應用更加方便和快捷。dva = React-Router + Redux + Redux-saga依賴安裝
yarn add dva
使用
需要例項化 dva
import React from 'react'import dva, { connect } from 'dva';import dvaModel from './store/dva';import DvaDemo from './Dva.jsx'const createHistory = require("history").createHashHistoryconst history = createHistory()// 建立應用const app = dva({ history: createHistory()});app.model(dvaModel)// 註冊檢視app.router(() => <DvaDemo />);// 啟動應用app.start('#app');
model建立一個 model 資料,基本的屬性
namespace 空間命名,全域性唯一state 初始資料reducers 修改資料,類似 vuex 中的 mutationseffects 獲取資料, 類似 vuex 中的 actionsubscription 訂閱資料const model = { namespace: 'dvamodel', state: { name: 'model dva', count: 0 }, reducers: { add(state) { state.count = state.count + 1 return { ...state } }, sub(state) { state.count = state.count - 1 return { ...state } } }, effects: { *addCount(action, { call, put }) { console.log(action, action.payload) // 拿到傳入的 payload yield put({type: 'add'}) }, *subCount(action, { call, put }) { console.log(action, action.payload) // 拿到傳入的 payload yield put({type: 'sub'}) } },}export default model
連線元件使用 connect 連線元件,都掛到 props 中去
import React from 'react'import { connect } from 'dva'function DvaDemo({dvamodel, dispatch}) { console.log(dvamodel) // 透過命令空間訪問 return ( <div> <h2>Dva</h2> <p>點選數:{dvamodel.count}</p> <button onClick={() => dispatch({ type: 'dvamodel/addCount', payload: 1 })}>點選 +</button> <button onClick={() => dispatch({ type: 'dvamodel/subCount', payload: 1 })}>點選 -</button> </div> )}export default connect((props) => props)(DvaDemo);
總結透過簡單的使用嘗試,感覺還是 Mobx 是最簡單
最新評論