选择正确的 React 状态管理解决方案的指南

本文探讨了React状态管理的重要性,从本地组件状态、组件道具、路由、Context API到各种状态管理库如Redux、Recoil、XState、Jotai、MobX和Zustand的使用,通过构建计数器应用示例来展示不同工具的特点和适用场景。文章还提到了React Query用于数据获取,并指出选择最佳状态管理工具应考虑项目需求和个人喜好。
摘要由CSDN通过智能技术生成

编者注 :本文于 2022 年 9 月 23 日更新,添加了关于为什么我们需要在 React 中进行状态管理的信息,添加了之前未包含在文章中的其他状态管理工具,例如 Jotai、MobX 和 Zusand,并添加了有关哪些状态管理的信息工具是 React 的最佳选择。

状态管理是每个开发人员在构建 React 应用程序时面临的基本挑战——而且它不是一个小问题。 在 React 中有很多有效的管理状态的方法,每一种都解决了一组突出的问题。

作为开发人员,重要的是不仅要了解不同的方法、工具和模式,还要了解它们的用例和权衡。

考虑状态管理的一个有用方法是根据我们在项目中解决的问题。 在本文中,我们将介绍在 React 中管理状态的常见用例,并了解何时应该考虑使用每种解决方案。 我们将通过构建一个简单的计数器应用程序来实现这一点。

  • 为什么我需要在 React 中进行状态管理?

  • React 中的本地组件状态

  • React 中的组件道具

  • React 中的路由

  • 使用 React 的 Context API useReducer

  • 使用 Redux 进行状态管理

  • 带有 Recoil 的原子状态

  • 带有 XState 的状态机

  • 使用 Jotai 进行原始和灵活的状态管理

  • 使用 MobX 进行简单、可扩展的状态管理

  • 使用 Zustand 进行状态管理

  • 使用 React Query 获取数据

  • 哪种状态管理工具最适合 React?

为什么我需要在 React 中进行状态管理?

首先,让我们讨论一下状态管理的重要性。 React 中的状态是一个 JavaScript 对象,它可以根据用户的操作来改变组件的行为。 状态也可以被认为是组件的内存。

React 应用程序是使用管理自己状态的组件构建的。 这适用于小型应用程序,但随着应用程序复杂性的增加,处理组件之间的共享状态变得越来越复杂和成问题。

这是一个简单的示例,说明金融科技应用程序中的成功交易如何影响其他几个组件:

  • 新交易将更改首页显示的可用余额

  • 新交易现在将显示为用户总交易历史中的最新交易

这就是为什么在开发可扩展的 React 应用程序时状态管理必不可少的原因。 从长远来看,如果状态管理不正确,应用程序无疑会遇到问题。 像这样不断地对应用程序进行故障排除和重建可能会变得乏味。

React 中的本地组件状态

实现计数器的最简单方法是使用本地组件状态和 useState钩。

import { useState } from 'react'
​
const Counter = () => {
    const [count, setCount] = useState(0)
​
    const increaseCount = () => {
        setCount(count + 1)
    }
​
    const decreaseCount = () => {
        if (count > 0) {
            setCount(count - 1)
        }
    }
    return (
        <div>
            <h1>{count}</h1>
            <button onClick={decreaseCount}>-</button>
            <button onClick={increaseCount}>+</button>
        </div>
    )
}
​
export default Counter

所以我们完成了,对吧? 文章结束? 不完全的。


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验 了解更多 →


如果这是一个真正的项目,那么将来我们可能会在应用程序的其他地方需要更多按钮和标题。 确保它们的外观和行为一致是一个好主意,这就是为什么我们应该将它们变成可重用的 React 组件的原因。

React 中的组件道具

转动我们的 Button和 Header分成不同的组件揭示了一个新的挑战。 我们需要某种方式在它们和主节点之间进行通信 Counter零件。

这就是组件道具发挥作用的地方。 对于我们的 Header组件,我们添加一个 text支柱。 对于我们的 Button,我们都需要一个 label道具和一个 onClick打回来。 我们的代码现在看起来像这样:

import { useState } from 'react'
​
const Header = ({ text }) => <h1>{text}</h1>
​
const Button = ({ label, onClick }) => (
    <button onClick={onClick}>{label}</button>
)
​
const Counter = () => {
    const [count, setCount] = useState(0)
​
    const increaseCount = () => {
        setCount(count + 1)
    }
​
    const decreaseCount = () => {
        if (count > 0) {
            setCount(count - 1)
        }
    }
    return (
        <div>
            <Header text={count} />
            <Button onClick={decreaseCount} label="-" />
            <Button onClick={increaseCount} label="+" />
        </div>
    )
}
​
export default Counter

这看起来很棒! 但是想象一下下面的场景:如果我们只需要在我们的家乡路线上显示计数并且有一个单独的路线怎么办? /controls我们在哪里显示计数和控制按钮? 我们应该怎么做呢?

React 中的路由

鉴于我们正在构建一个单页应用程序,现在我们需要处理第二个状态——我们所在的路线。 例如,让我们看看如何使用 React Router 来完成。

import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom'
import { useState } from 'react'
​
const Header = ({ text }) => <h1>{text}</h1>
​
const Button = ({ label, onClick }) => (
    <button onClick={onClick}>{label}</button>
)
​
const Home = ({ count }) => {
    return <Header text={count} />
}
​
const Controls = ({ count, decreaseCount, increaseCount }) => {
    return (
        <>
            <Header text={count} />
            <Button onClick={decreaseCount} label="-" />
            <Button onClick={increaseCount} label="+" />
        </>
    )
}
​
const App = () => {
    const [count, setCount] = useState(0)
    const increaseCount = () => {
        setCount(count + 1)
    }
    const decreaseCount = () => {
        if (count > 0) {
            setCount(count - 1)
        }
    }
​
    return (
        <Router>
            <nav>
                <Link to="/">Home</Link>
                <Link to="/controls">Controls</Link>
            </nav>
            <Switch>
                <Route path="/controls">
                    <Controls
                        increaseCount={increaseCount}
                        decreaseCount={decreaseCount}
                        count={count}
                    />
                </Route>
                <Route path="/">
                    <Home count={
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pxr007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值