在 React 中不使用 Redux 时遇到的问题
在 React 中组件通信的数据流是单向的,顶层组件可以通过 props 属性向下层传递数据,而下层组件不能向上层组件传递数据,要实现下层组件修改数据,需要上层组件传递修改数据的方法到下层组件。当项目越来越大的时候,组件之间传递数据变得越来越困难。
在 React 项目中加入 Redux 的好处
使用 Redux 管理数据,由于 Store 独立于组件,使得数据管理独立于组件,解决了组件与组件之间传递传递数据困难的问题。
React + Redux 使用
下载 Redux
npm install redux react-redux
复制代码
回顾 Redux 工作流程
- 组件通过 dispatch 方法触发 Action
- Store 接收 Action 并将 Action 分发给 Reducer
- Reducer 根据 Action 类型对状态进行更改并将更改后的转态返回给 State
- 组件订阅了Store中的状态,Store中的状态更新会同步到组件
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)(组件名称);
复制代码
3. 组件更改Store中的数据
- 定义 action
{ type: '描述对数据要进行什么样的操作' }
复制代码
action 是改变状态的唯一途径
- 组件触发 action
this.props.dispatch({ type: '描述对数据要进行什么样的操作' })
复制代码
- 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 传递参数
- 传递参数
<button onClick={() => increment(5)}> + 5 </button>
复制代码
- 接收参数,传递 reducer
export const increment = payload => ({ type: INCREMENT, payload });
复制代码
- 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