详解在React项目中集成Redux

15 篇文章 1 订阅

关于Redux

官网:https://redux.js.org/
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。具有以下特点(以下内容根据官网内容翻译):

  1. 可预测的
    Redux 可帮助您编写行为一致、在不同环境(客户端、服务器和本机)中运行且易于测试的应用程序。
  2. 集中管理
    将应用程序中的状态和逻辑集中管理,以实现强大的功能,如撤消/重做、状态持久性等。
  3. 可调试
    借助于Redux DevTools工具,可以轻松的追踪应用状态变更的时间、位置、原因以及方式。Redux的架构允许您记录更改,使用“time-travel debugging”,甚至将完整的错误报告发送到服务器。
  4. 灵活性
    Redux 适用于任何 UI 层,并具有庞大的插件生态系统来满足您的需求。

以下内容将详细讲解React项目如果集成Redux

集成Redux

1. 安装Redux

通过以下命令安装reduxreact-redux@reduxjs/toolkit

npm install redux --save
# React 绑定库
npm install react-redux --save
npm install @reduxjs/toolkit --save

#开发者工具
npm install --save-dev redux-devtools

2.创建reducers

Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。

我们可以在项目src目录下创建src/reducers/nodes.ts的文件,该文件用来管理node相关状态信息,当然也可以创建其他的文件来管理其他状态=。原则上一个reducer管理一种类型的状态,如创建todo.ts管理todo相关信息。

// nodes.ts
type ActionType = 'ADD_NODE' | 'DEL_NODE';

interface Action {
    type: ActionType;
    value: any;
}

const nodes = (state = [], action: Action) => {
    switch (action.type) {
        case 'ADD_NODE': {
            // 往数组最后添加value
            return [...state, action.value];
        }
        case 'DEL_NODE': {
            // 过滤掉元素,达到删除的效果
            return state.filter(item => item !== action.value);
        }
    }

    return state;
}

export default nodes;

3. 整合reducers

我们需要把多个不同 reducer 函数,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore 方法。
创建src/reducers/index.ts文件,用于整合src/reducers目录下的多个reducer。

// src/reducers/index.ts
import { combineReducers } from 'redux';
import nodes from './nodes';
// 可以引入其他reducer

const reducers = combineReducers({
    nodes,
    // 可以添加其他reducer
});

4. 创建store

创建一个 Redux store 来以存放应用中所有的 state。
注意:老版本的redux通过createStore方法创建store,新版本(指的是4.2+)则将该方法标记为废弃@deprecated,并建议通过configureStore来创建store。src/reducers/index.ts完整的代码如下:

// src/reducers/index.ts
import {combineReducers, createStore} from 'redux';
import { configureStore } from '@reduxjs/toolkit';
import nodes from './nodes';
// 可以引入其他reducer

const reducers = combineReducers({
    nodes,
    // 可以添加其他reducer
});

export const store = configureStore({reducer: reducers});

5. 创建actions

Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说通过 store.dispatch() 方法将 action 传到 store。

// src/sctions/index.ts
export const addNode = node => ({
    type: 'ADD_NODE',
    value: node
});

export const delNode = node => ({
    type: 'DEL_NODE',
    value: node
});

6. 调用store.dispatch(action)

在具体业务逻辑代码中,通过调用store.dispatch(action)方法来分发 action,这是触发 state 变化的惟一途径。
store.dispatch(action)会使用当前 getState() 的结果和传入的 action 以同步方式的调用 store 的 reduce 函数。返回值会被作为下一个 state,同时变化监听器(change listener)会被触发。例:

import {store} from '../reducers'; // 引用store

// 业务代码...
store.dispatch(addNode(model.id));
// 业务代码...

7. connect

connect() 属于React中的高阶组件,作用是连接 React 组件与 Redux store,使得React组件能过访问到Redux store。

// src/index.ts
import {store} from './reducers';

// ...
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  // 根节点需要被<Provider store>包裹
  <Provider store={store}>
    <MyRootComponent />
  </Provider>
);

业务组件:

// src/components/my-component.ts
import {Dispatch} from 'redux';
import {connect} from 'react-redux';
import {store} from '../reducers';


interface IMyComponentProps{
    nodes: string[];
    addNode: (value: string| null) => void;
}
interface IMyComponentState{
}

class MyComponentextends React.Component<IMyComponentProps, IMyComponentState> {
    // 省去MyComponent组件部分代码

	method(node: string) {
	    // 调用props中的addNode
        this.props.addNode(node);
    }

    render() {
        return (
            // 访问redux中的nodes
            <div>{this.props.nodes.length}</div>
        )
    }
}

interface IStoreState {
    nodes: string[];
}

const mapStateToProps = (state: IStoreState, ownerProps: IMyComponentProps): { nodes: string[] } => ({
    nodes: state.nodes
});

const mapDispatchToProps = (dispatch: Dispatch, ownProps: IMyComponentProps): {
    addNode: (value: string | null) => void,
    delNode: (value: string | null) => void,
} => ({
    addNode: (value: string | null) => dispatch({type: 'ADD_NODE', value}),
    delNode: (value: string | null) => dispatch({type: 'DEL_NODE', value}),
});

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(MyComponent);

方法connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])的主要作用是连接 React 组件与 Redux store。 连接操作不会改变原来的组件类。 反而返回一个新的已与 Redux store 连接的组件类。
connect()参数如下:

  • [mapStateToProps(state, [ownProps]): stateProps] (Function): 如果定义该参数,组件将会监听 Redux store 的变化。任何时候,只要 Redux store 发生改变,mapStateToProps函数就会被调用。该回调函数必须返回一个纯对象,这个对象会与组件的 props 合并。如果你省略了这个参数,你的组件将不会监听 Redux store。如果指定了该回调函数中的第二个参数 ownProps,则该参数的值为传递到组件的 props,而且只要组件接收到新的 props,mapStateToProps 也会被调用(例如,当 props 接收到来自父组件一个小小的改动,那么你所使用的 ownProps 参数,mapStateToProps 都会被重新计算)。

  • [mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function): 如果传递的是一个对象,那么每个定义在该对象的函数都将被当作 Redux action creator,对象所定义的方法名将作为属性名;每个方法将返回一个新的函数,函数中dispatch方法会将action creator的返回值作为参数执行。这些属性会被合并到组件的 props 中。

    • 如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由你来决定如何返回一个对象,这个对象通过 dispatch 函数与 action creator 以某种方式绑定在一起。
  • [mergeProps(stateProps, dispatchProps, ownProps): props] (Function): 如果指定了这个参数,mapStateToProps()mapDispatchToProps() 的执行结果和组件自身的 props 将传入到这个回调函数中。该回调函数返回的对象将作为 props 传递到被包装的组件中。你也许可以用这个回调函数,根据组件的 props 来筛选部分的 state 数据,或者把 props 中的某个特定变量与 action creator 绑定在一起。如果你省略这个参数,默认情况下返回 Object.assign({}, ownProps, stateProps, dispatchProps) 的结果。

  • [options] (Object) 如果指定这个参数,可以定制 connector 的行为。

    • [pure = true] (Boolean): 如果为 true,connector 将执行 shouldComponentUpdate 并且浅对比 mergeProps 的结果,避免不必要的更新,前提是当前组件是一个“纯”组件,它不依赖于任何的输入或 state 而只依赖于 props 和 Redux store 的 state。默认值为 true
    • [withRef = false] (Boolean): 如果为 true,connector 会保存一个对被包装组件实例的引用,该引用通过 getWrappedInstance() 方法获得。默认值为 false

后记

至此React项目如何集成Redux讲解完毕,如有疑问,欢迎私信或者评论区交流。
也希望各位能够点个赞👍或者收藏⭐
:)


扩展阅读:
React + Antd实现动态切换主题功能
React + Antd实现动态切换主题功能之二(默认主题与暗黑色主题切换)
React + Router + Antd实现多标签页功能(具体代码实现)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值