create-react-app全家桶状态管理之redux

前言:该文章主要讲解如何在 react 项目中接入 redux 数据状态管理,假设你已经阅读过这篇文章中的前半篇(除去添加数据管理这一段)。

  • 安装需要的依赖包
npm install redux react-redux --save
  • 新建需要的文件夹
    src 目录下新建 actionsreducersconstants 文件夹,actions 存放分发的 action函数;reducers 存放单个的 reducerconstants 存放分发 actiontype 常量。

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

现在你可以编写你自己的 actionreducer 了。

  • 配合浏览器安装辅助工具 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 就能看见以下效果

create-react-app全家桶状态管理之redux_第1张图片
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 树的值进行修改,将修改后的数据 actionreducer中,结果 reducer 的数据更新了,但是页面并没有重新渲染

原因: reduxstate 是引用,直接对 state 的值进行更改时,store 内部的 state 值同样也改变了,这样导致 redux 认为 dispatch 前后 state 没有改变,就不会重新渲染UI,实际上 state 已经改变了

你可能感兴趣的:(create-react-app全家桶状态管理之redux)