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 
复制代码

这个没什么好说的,就一个项目建立脚手架,能够包含测试 编译 部署等流程 就像使用种组装了一辆汽车 而用户来选择需不须要加车窗 轮子等部件

参考文章

相关文章
相关标签/搜索