react進行狀態管理的幾種方式

redux

最基礎的就是使用 redux 來處理react

這裏是展現組件結構npm

import { connect } from 'react-redux'
import { valueAdd, valueReduce } from './redux/action'

class Main extends Component {
  render () {
    return (
      <div className="App"> <header className="App-header"> <p onClick={() => this.props.valueAdd()} > 點擊 + 1 </p> <p onClick={() => this.props.valueReduce()} > 點擊 - 1 </p> <div> i am {this.props.number} </div> </header> </div>
    )
  }
const MainBox = connect(
  (state) => { return { number: state.number }},
  dispatch => {
    return {
      addNumber: () => { dispatch(valueAdd()) },
      reduceNumber: () => { dispatch(valueReduce()) }
    }
  }
)(Main)
export default MainBox
複製代碼

藉助 bindActionCreators 調整一下redux

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as action from './redux/action'

@connect(
  ({number}) => ({number}),
  dispatch => bindActionCreators(action, dispatch)
)
class Main extends Component {
  render () {
    return (
      <div className="App"> <header className="App-header"> <p onClick={() => this.props.valueAdd()} > 點擊 + 1 </p> <p onClick={() => this.props.valueReduce()} > 點擊 - 1 </p> <div> i am {this.props.number} </div> </header> </div>
    )
  }
}
export default Main
複製代碼

redux-saga

文檔閱讀數組

經常使用API

方法 建議
takeEvery 監聽派發的動做,若是action type匹配的話,會執行對應的函數
put 派發Action, 能夠理解成爲redux中的dispatch函數
call 調用函數執行,阻塞
fork 調用函數執行,不會阻塞

使用方式

對比於 redux,使用saga的時候只須要調整一下store的生成bash

import { applyMiddleware, createStore } from 'redux';
import createSagaMiddleware from "redux-saga";
import rootSaga from "./saga" //引入rootSaga
import reducer from './reducer'
let sagaMiddleware = createSagaMiddleware()

export const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware),
);
sagaMiddleware.run(rootSaga); // 開始執行rootSaga
複製代碼

添加一個 saga 文件app

function * add () {
  // 派發Action
  yield put({ type: ACTION_ADD })
}

function * reduce () {
  yield put({type: ACTION_REDUCER})
}

function * watchAdd() {
 // 監聽派發給倉庫的動做,若是動做類型匹配的話,會執行對應的監聽生成器
  yield takeEvery(ACTION_ADD_SAGA, add)
  yield takeEvery(ACTION_REDUCER_SAGA, reduce)
}

export default function * rootSaga() {
  yield watchAdd()
}
複製代碼

saga 有三種,作工做的 進行監聽的 以及 rootsage異步

1 worker saga 作具體的工做,如調用API,進行異步請求,獲取異步封裝結果函數

2 watcher saga 監聽被dispatch的actions,當接受到action或者知道其被觸發時,調用worker執行任務測試

3 root saga 啓動saga的惟一入口ui

dva

dva 能夠視爲內部封裝了redux-saga

安裝

npm install -g dva-cli
複製代碼

使用dva生成項目

dva new xxxname
複製代碼

dva 項目結構

dva

dva 的文件結構命名有點奇怪, 好比這個 routes 文件夾 其實不是路由處理,裏面是組件,(與該路由對應的組件)

models 則是將 action reducer action_type 編寫到一塊兒了

入口文件 index.js

在index.js 實現一些配置 好比 定義默認state 添加中間件 引入model=

import dva from 'dva';
import {createLogger} from 'redux-logger';
// 1. Initialize 
const app = dva({});

// 2. Plugins
// app.use({});

// 3. Model
app.model(require('./models/main').default);
app.model(require('./models/users').default);

// 4. Router
app.router(require('./router').default);

// 5. Start
app.start('#root');
複製代碼

能夠設置的所有屬性參數爲

const app = dva({
  history, // 路由控制 
  initialState, // 基礎state 優先級高於 model 中的 state
  onError, // effect 執行錯誤或 subscription 經過 done 主動拋錯時觸發,可用於管理全局出錯狀態
  onAction, // 在action被dispatch時觸發,用於註冊 redux 中間件。支持函數或函數數組格式
  onStateChange, // 顧名思義,在state變更的時候觸發
  onReducer,
  onEffect,
  onHmr,
  extraReducers,
  extraEnhancers,
})
複製代碼
  • app.use

能夠添加中間件

  • app.model

全部的model都要經過這個方法掛載到app

  • app.router

掛載定義的路由

  • app.start

啓動app

核心部分 models

export defult {
  namespace: '',
  state: '',
  reducers: {},
  effects: {},
  subscriptions: {}
}
複製代碼
key 含義
namespace model 的命名空間,是在全局 state 上的屬性
state state 初始值
reducers 惟一能夠修改 state 的地方,由 action 觸發
effects 用於處理異步操做和業務邏輯,不直接修改 state。由action 觸發,
subscriptions 用於訂閱一個數據源,而後根據須要 dispatch 相應的 action

感受若是項目決定使用 redux-saga 能夠考慮直接使用 dva

流程圖

umi 嗚咪

mimi

(和喵喵並無什麼關係)

npm i -g umi
複製代碼

建立文件

mkdir project && cd project && yarn create umi && cnpm i 
複製代碼

這個沒什麼好說的,就一個項目建立腳手架,能夠包含測試 編譯 部署等流程 就像使用種組裝了一輛汽車 而用戶來選擇需不須要加車窗 輪子等部件

參考文章

相關文章
相關標籤/搜索