前言:该文章主要讲解如何在 react 项目中接入 redux 数据状态管理,假设你已经阅读过这篇文章中的前半篇(除去添加数据管理这一段)。
- 安装需要的依赖包
npm install redux react-redux --save
-
新建需要的文件夹
在src目录下新建actions、reducers、constants文件夹,actions存放分发的action函数;reducers存放单个的reducer;constants存放分发action的type常量。在
reducers中创建index.js,用来组合单个的reducer,输出根state
import { combineReducers } from 'redux'
export default combineReducers({})
- 修改
webpack文件来设置别名
alias: {
styles: paths.appStyles,
routes: paths.appRoutes,
components: paths.appComponents,
actions: paths.appActions,
constants: paths.appConstants,
reducers: paths.appReducers,
...
- 添加
redux-thunk异步中间件
npm install redux-thunk --save
- 修改
routes文件夹下的index.js
...
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose } from 'redux'
import thunkMiddleware from 'redux-thunk'
import rootReducer from 'reducers'
...
const store = createStore(
rootReducer,
compose(applyMiddleware(thunkMiddleware)),
)
const App = () => (
<Provider store={store}>
<Routes />
</Provider>
)
现在你可以编写你自己的 action,reducer 了。
- 配合浏览器安装辅助工具
Redux DevTools
Chrome浏览器安装Redux DevTools扩展程序,修改routes中的index.js
let composeEnhancers = compose
if (process.env.NODE_ENV === 'development') {
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // eslint-disable-line
}
const store = createStore(
rootReducer,
composeEnhancers(applyMiddleware(thunkMiddleware)),
)
在浏览器界面打开 Redux DevTools 就能看见以下效果
DevTools.png
编写middleware
如果需要自定义的 middleware,很简单,这个 middleware 只接收一个 action,执行后也需要返回一个 action;如果需要执行下一步,调用 next(action) 即可。
- 日志的中间件
const logger = store => next => (action) => {
console.log('dispatching', action);
const result = next(action);
console.log('next state', store.getState());
return result;
};
修改 routes文件夹下的 index.js,将该日志中间件加上
const store = createStore(
rootReducer,
composeEnhancers(applyMiddleware(thunkMiddleware, logger)),
)
当然还是附上项目地址
欢迎指正、star
中途遇到的问题
1.reducer
- 控制台提示
No reducer provided for key 'xxxReducer'
出现情况: 两个reducer文件如下写
const reducer = () => {};
export default reducer;
在reducer汇总文件分别使用
export default combineReducers({
reducer1,
reducer2,
});
这种写法会出现No reducer provided for key 'xxxReducer'
解决方法:
- 让每个reducer命名不重复
const reducer1 = () => {};
export default reducer1;
- 直接这样导出
export default () => {}
redux不更新数据问题
问题: 在 component 中直接对 state 树的值进行修改,将修改后的数据 action 到 reducer中,结果 reducer 的数据更新了,但是页面并没有重新渲染
原因: redux 的 state 是引用,直接对 state 的值进行更改时,store 内部的 state 值同样也改变了,这样导致 redux 认为 dispatch 前后 state 没有改变,就不会重新渲染UI,实际上 state 已经改变了












网友评论