react整合原生redux(二)
前言
在react整合原生redux(一)已经完成了一个基本的应用框架,但是在分发action的时候,并不能在action里写逻辑,换言之action始终只是json对象,不能是一个函数,虽然可以在视图生命周期内写逻辑方法改变state的数值,但是长此以往,会造成项目臃肿,维护困难,所以react-thunk中间件由此而生
项目创建
增加依赖包
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(三)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。