React + Redux

在 React 中不使用 Redux 时遇到的问题

在 React 中组件通信的数据流是单向的,顶层组件可以通过 props 属性向下层传递数据,而下层组件不能向上层组件传递数据,要实现下层组件修改数据,需要上层组件传递修改数据的方法到下层组件。当项目越来越大的时候,组件之间传递数据变得越来越困难。

image.png

在 React 项目中加入 Redux 的好处

使用 Redux 管理数据,由于 Store 独立于组件,使得数据管理独立于组件,解决了组件与组件之间传递传递数据困难的问题。

image.png

React + Redux 使用

下载 Redux

npm install redux react-redux
复制代码

回顾 Redux 工作流程

  1. 组件通过 dispatch 方法触发 Action
  2. Store 接收 Action 并将 Action 分发给 Reducer
  3. Reducer 根据 Action 类型对状态进行更改并将更改后的转态返回给 State
  4. 组件订阅了Store中的状态,Store中的状态更新会同步到组件

image.png

Redux 使用步骤

1. 创建 Store 和 Reducer
  • 创建 Store 和 Reducer

创建 Store 需要使用 createStore 方法,方法执行后的返回值就是 Store,createStore 方法需要从 redux 中引入

  • createStore 方法的第一个参数需要传递 reducer
  • reducer 是一个函数,函数返回什么,store 中就存储什么,函数名称自定义
import { createStore } from 'react';

function reducer () {
  return { count: 1 };
}
const store = createStore(reducer);
复制代码
2. 组件获取 Store 中的数据
  • 将store中的数据放在Provider组件中,Provider组件是存储共享数据的地方。
import { Provider } from 'react-redux';
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
);
复制代码
  • 组件使用connect方法订阅数据、获取数据并将数据通过props传递给组件
import { connect } from 'react-redux';
const mapStateToProps = state => ({
  count: state.count
})
export default connect(mapStateToProps)(组件名称);
复制代码

image.png

3. 组件更改Store中的数据
  1. 定义 action
{ type: '描述对数据要进行什么样的操作' }
复制代码

action 是改变状态的唯一途径

  1. 组件触发 action
this.props.dispatch({ type: '描述对数据要进行什么样的操作' })
复制代码
  1. reducer 接收 action,针对 action 对数据进行处理并返回
const initialState = { count: 0 };
const reducer = (state = initialState, action) => {
  awitch (action.type) {
   case '描述对数据要进行什么样的操作':
     return { count: state.count + 1 };
   dafault:
     return state;
  }
}
复制代码
4. 为 action 传递参数
  1. 传递参数
<button onClick={() => increment(5)}> + 5 </button>
复制代码
  1. 接收参数,传递 reducer
export const increment = payload => ({ type: INCREMENT, payload });
复制代码
  1. reducer 根据接收到的数据进行处理
const reducer = (state = initialState, action) => {
  awitch (action.type) {
   case '描述对数据要进行什么样的操作':
     return { count: state.count + action.payload };
   dafault:
     return state;
  }
}
复制代码

优化

使用 Action Creator 函数将触发 Action 的代码独立成函数

在组件模板通过调用this.props.dispatch({ type: '描述对数据要进行什么样的操作' })方法触发action,造成HTML模板在视觉上的混乱,所以优化成:

const mapDispatchToProps = dispatch => ({
  increment () {
    dispatch({ type: 'increment'})
  },
  decrement () {
    dispatch({ type: 'decrement'})
  }
})
export default connect(mapStateToProps, mapDispatchToProps)(组件名称);
复制代码
Action Creators 函数绑定

触发 Action 的函数,内部代码重复率非常高,所以 React 提供了方法帮我们生成这些函数,代替开发者手写

// store.actions.couter.aciton.js
export const increment = () => ({ type: 'increment' })
export const decrement = () => ({ type: 'decrement' })
// 组件
import { bindActionCreators } from 'redux';
import * as counterAction from '../store/actions/counter.action.js';
const mapDispatchToProps = dispatch => ({
  ...bindActionCreators(counterActions, dispatch)
})
复制代码
将 Action 类型字符串独立成常量

Action 类型字符串组件在触发 Action 时需要使用,Reducer 在接收 Action 时也需要使用,由于字符串不存在代码提示,存在写错的风险,所以将它独立成常量。

拆分 Reducer

当要管理的数据越来越多时,reducer中的代码将会变得越来越大,Redux允许将一个大的reducer拆分成若干个小的reducer,最后进行合并使用。

import { combineReducers } from 'redux';

export default combineReducers ({
  counter: counterReducer,
  modal: modalReducer
})
复制代码

拆分后获取数据

import { connect } from 'react-redux';
const mapStateToProps = state => ({
  count: state.counter.count
})
export default connect(mapStateToProps)(组件名称);
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享