react整合原生redux二

51次阅读

共计 2055 个字符,预计需要花费 6 分钟才能阅读完成。

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.js
import {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.js
import 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(三)

正文完
 0