redux
redux工作流程示意图
actions
函数形式,返回 action
对象,通常具有type
属性。负责指令的生成,页面通过 store.dispatch(action)
向 store
发送数据修改的请求。
reducers
一个纯函数,接收两个参数 (previousState, action)
第一个表示修改之前的 state 的值,action
是上一步页面通过 store.dispatch(action)
向 store
传递的 action
。reducers
通过 action
的 type
的值进行不同的处理,返回一个新的变量 newState
。reducers
不能直接修改传递进来的 previousState
.
store
通过 const store = createStore(reducer);
创建一个 store
对象。
需要导入到 React 组件文件中,通过 this.state = store.getState();
让组件获取 store 中的数据;
并在 componentDidMount
生命周期函数中订阅 store 中数据的变化:
componentDidMount(){
store.subscribe(()=>{
this.setState(store.getState());
});
}
//初始化store
const store = createStore(reducers);
//获取 state
store.getState();
// 触发 action,请求修改数据
store.dispatch(action);
// 订阅数据变化的回调函数
store.subscribe(()=>{
//to do
});
react-redux
react-redux 是将 react 和 redux 结合使用
<Provider>
组件, 可以简化我们每次导入到 React 组件文件 store 的工作。
import { Provider } from "react-redux";
<Provider store={store}> //store 传进去
<TodoList/>
</Provider>
mapStateToProps
函数,将 store 中的state
转为组件的props
mapDispatchToProps
函数, 传入dispatch
用于触发 action。connect
函数。-
const mapStateToProps = (state)=>({ inputValue: state.inputValue, list: state.list }) const mapDispatchToProps = (dispatch) => ({ hanldeAdd: ()=>{ dispatch(addItem()); }, changeInputValue: (e)=>{ dispatch(changeValue(e.target.value)); }, deleteItem: (key)=>{ dispatch(deleteItem(key)) } }) // 接收 mapStateToProps 和 mapDispatchToProps 两个参数, //并返回一个函数,这个函数接受 TodoList 返回一个封装的组件。 export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
异步
两个处理异步的 Redux 的中间件
redux-thunk
和redux-saga
redux-thunk
同 redux 一起使用,增强了 redux 的功能。之前 actions
返回一个对象,异步的 action 可以返回一个函数:
export const initList = (list)=>({
type: INIT_LIST,
list
});
export const getInitList = ()=> {
return function(dispatch){
axios.get("/api/initList.json").then(res=>{
//调用上面的initList,向store发送数据修改的请求
//然后reducers通过action的type的值进行处理,返回一个新的state
dispatch(initList(res.data))
})
}
}
同时,创建 store 的时候也要加上 redux-thunk
这个中间件:
import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk';
import reducer from '../reducers';
const store = createStore(reducer, applyMiddleware(thunk));
export default store;
详细配置请参考redux-thunk的github文档
redux-saga
redux-saga 也是 redux 的一个中间件,可以处理异步 action 。通过 takeEvery(GET_INIT_LIST, getInitList)
监听 action.type 是GET_INIT_LIST
的action操作,会执行 getInitList
方法,去获取异步数据。
import React from "react";
import store from '../store';
import { getInitList } from "../actions/actionCreator.js";
class TodoList extends React.Component{
componentDidMount(){
const action = getInitList();
store.dispatch(action);
}
//。。。。
}
export default TodoList;
./saga/index.js
import {takeEvery, put} from 'redux-saga/effects';
import { GET_INIT_LIST } from "../../common/actionTypes.js";
import { initList} from "../actions/actionCreator.js";
import axios from 'axios';
function* getInitList(){
try{
const res = yield axios.get("/api/initList.json");
const action = initList(res.data);
//yield put向store发送数据修改的请求,然后reducers通过action的type的值进行处理,返回一个新的state
yield put(action);
}catch(e){
console.log("initList.json网络请求失败")
}
}
function* mySaga(){
yield takeEvery(GET_INIT_LIST, getInitList);
}
export default mySaga;
同时,创建 store 的时候也要加上 redux-saga
这个中间件以及引入../saga/index.js:
import { createStore, applyMiddleware } from "redux";
import createSagaMiddleware from 'redux-saga';
import reducer from '../reducers';
import mySaga from '../saga/index';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(reducer, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(mySaga);
export default store;
详细配置请参考redux-saga的github文档