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(三)