前端宝典之八:React状态管理全解析并手写实现

前言:

React 中用于状态管理的hook及库有:useState、useReducer、useContext、useReducer + useContext和一些第三方的库如redux、mobx等。

1、useState

单一组件某个具体状态

2、useReducer

单一组件中多个状态管理,策略分发机制统一管理

3、useContext

创建了一个全局状态机制,可分发给下面所有的children

4、useReducer + useContext

使用 React.createContext 创建一个 Context 对象。这个 Context 将用于在组件树中传递全局状态和更新状态的方法,Context 通常会有一个 Provider 组件,Provider 组件内部,使用 useReducer 来管理全局状态

5、redux库

Redux 的原理是通过单一的不可变的存储中心(store)来保存应用的状态,利用纯函数(reducer)来处理状态的更新,借助 action 来描述状态的变化意图,实现了可预测的状态管理和组件之间的数据共享。

一、useReduceruseState区别

由于useReducer是用在单一组件中多个状态管理,是否可以用useState代替呢?
useReduceruseState在某些情况下可以相互替代,但它们也有一些不同之处:

1、功能和使用场景

1.1 useReducer通常适用于以下场景:

复杂的状态逻辑管理

当状态的更新逻辑较为复杂,包含多个子状态之间的相互依赖关系或多个不同的操作类型时,useReducer可以使代码更清晰、更具可读性和可维护性。

共享状态逻辑

如果多个组件需要共享相同的状态更新逻辑,useReducer可以将 reducer 函数提取出来,方便在不同组件中复用。

优化性能

在某些情况下,useReducer会比useState更高效,特别是当状态更新频繁且计算量较大时,因为 reducer 函数通常是纯函数,React 可以更有效地进行优化。

1.2 useState则更适合以下场景:

简单的状态管理

当状态更新逻辑比较简单,只有一个或几个基本的状态值需要管理时,useState是一个更直接和简洁的选择。

小型组件

对于小型组件或不需要复杂状态管理的组件,useState的语法更简单,代码量更少。

2、代码结构和可读性

2.1 useReducer

使用useReducer时,需要定义一个 reducer 函数来处理状态的更新。这个 reducer 函数接收当前的状态和一个动作(action)作为参数,并返回新的状态。

import {
    useReducer } from 'react';

const initialState = {
    count: 0 };

function reducer(state, action) {
   
    switch (action.type) {
   
        case 'increment':
            return {
    count: state.count + 1 };
        case 'decrement':
            return {
    count: state.count - 1 };
        default:
            return state;
    }
}

function Counter() {
   
    const [state, dispatch] = useReducer(reducer, initialState);

    return (
        <div>
            <p>Count: {
   state.count}</p>
            <button onClick={
   () => dispatch({
    type: 'increment' })}>+</button>
            <button onClick={
   () => dispatch({
    type: 'decrement' })}>-</button>
        </div>
    );
}

这种方式将状态更新的逻辑集中在 reducer 函数中,使得代码结构更清晰,尤其是当状态更新逻辑复杂时,更容易理解和维护。

2.2 useState

useState的语法相对简单,直接返回一个状态值和一个更新状态的函数。

import {
    useState } from 'react';

function Counter() {
   
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>Count: {
   count}</p>
            <button onClick={
   () => setCount(count + 1)}>+</button>
            <button onClick={
   () => setCount(count - 1)}>-</button>
        </div>
    );
}
对于简单的状态更新,`useState`的代码更简洁直观,易于理解。

3、性能优化方面

3.1 useReducer

在某些情况下,useReducer可以更好地进行性能优化。因为 reducer 函数是纯函数,React 可以更容易地跟踪状态的变化,并根据需要进行优化。例如,当状态更新是基于前一个状态值计算时,useReducer可以确保每次更新都是基于最新的状态值,避免潜在的竞态条件。
如果状态更新的计算量较大,将计算逻辑放在 reducer 函数中,可以让 React 更好地理解状态的变化过程,从而进行更有效的优化。

3.2 useState

useState在简单的状态更新场景下性能表现也很好。但如果在状态更新过程中存在复杂的计算或依赖关系,可能需要手动处理一些性能优化问题,比如使用useMemouseCallback来避免不必要的重新渲染。

综上所述,虽然在单一组件中,对于简单的状态管理,useState可能更方便快捷,但对于复杂的状态逻辑和需要更好的性能优化的场景,useReducer是一个很好的选择。在实际开发中,可以根据具体的需求和项目特点来决定使用哪种方式。

二、 useReducer + useContext

以下是一个使用 useReduceruseContext 结合 TypeScript 来模拟类似 Redux 功能的代码示例:

1. 创建 types.ts 文件来定义接口和类型:

// 定义动作类型
export enum ActionTypes {
   
    INCREMENT 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值