react整合原生redux(二)
前言
在react整合原生redux(一)已经完成了一个基本的应用框架,但是在分发action的时候,并不能在action里写逻辑,换言之action始终只是json对象,不能是一个函数,虽然可以在视图生命周期内写逻辑方法改变state的数值,但是长此以往,会造成项目臃肿,维护困难,所以react-thunk中间件由此而生
项目创建
参考 react整合原生redux(一)
增加依赖包
yarn add redux-thunk -s
src文件目录
|-app.js
|-store.js
|-index.js
|-actions.js
多了一个actions.js文件,里面存放带逻辑的action
action.js内容
// actions.js/** * redux-thunk action格式为一个函数,返回值是使用了dispatch的函数 * 基本格式 * function () { * return function (dispatch) { * dispatch(...) * } * } */export const fetchListAction = param => { return dispatch => { // 模拟异步请求请求数据(fetch,axios等) new Promise(resolve => { setTimeout(() => { const data = { code: 0, msg: "ok", data: { list: ["hello", "thunk"], param } }; resolve(data); }, 2000); }).then(result => { dispatch({ type: "SAVE", payload: result.data }); }); };};
store改动
引入redux-thunk
完整代码
// store.jsimport { createStore, applyMiddleware } from "redux";import thunk from "redux-thunk";import { composeWithDevTools } from "redux-devtools-extension"; //chrome redux调试工具// state初始值const initState = { list: ["a", "b"]};// reducer格式const reducer = (state = initState, action) => { const { type, payload } = action; // action的type处理 if (type === "SAVE") { return Object.assign({}, state, payload); } return state;};/** * 实例化store * 参数1: reducer * 参数2: 中间件 */export default createStore( reducer, composeWithDevTools(applyMiddleware(thunk)));
在app.js中调用
主要是这段
useEffect(() => { store.dispatch(fetchListAction({ id: 1 }));}, []);
完整代码
// app.jsimport React, { useState, useEffect } from "react";import store from "./store";import { fetchListAction } from "./actions";export default () => { // 获取store中的state,并放进hook函数,类似this.setState(store.getState()) const [state, setState] = useState(store.getState()); useEffect(() => { // store订阅函数,当state通过store.dispatch分发action改变时此函数自动执行 store.subscribe(() => { setState(store.getState()); //重新设置组件state的值,使视图更新 }); }, []); // []表示只执行一次 // 模拟首次载入页面请求数据 useEffect(() => { store.dispatch(fetchListAction({ id: 1 })); }, []); const { list } = state; const addList = () => { list.push(Date.now()); store.dispatch({ type: "SAVE", payload: { list } }); //分发一个 action 对象 }; return ( <div> <button onClick={addList}>add</button> <ul> {list.map(v => { return <li key={v}>{v}</li>; })} </ul> </div> );};
这样就可以应付一般中小型项目的需求了,查看完整代码
一般大型项目用redux-saga,请看react整合原生redux(三)