React 状态管理:何时使用 Context API 而不是 Redux React 状态管理:何时使用 Context API 而不是 Redux

2025-06-07

React 状态管理:何时使用 Context API 而不是 Redux

React 状态管理:何时使用 Context API 而不是 Redux

React 状态管理:何时使用 Context API 而不是 Redux

React 是一个主要用于构建交互式且极具吸引力的前端的库。它采用基于组件的架构,以实现最大程度的代码复用性以及其他诸多功能。状态管理是任何领域的开发人员都必须面对的问题,在 React 中,开发人员也面临着诸多挑战,而状态管理库 Redux 解决了其中大部分问题。随着时间的推移,React 不断演进,尝试自行解决其中一些问题,Context API 就是这种尝试的成果。本文将讨论 Redux 和 Context API,并提出一些指导原则,帮助您在两者之间做出选择。

先决条件

本文面向拥有丰富 JavaScript 和 ReactJS 编写 Web 应用程序经验的开发者。如果您熟悉其他前端框架/库,例如 VueJS、AngularJS、SvelteJS 等,仍然可以参考本文。

✅ 具有使用 ReactJS 编写 Web 应用程序的经验
✅ 具有使用 Redux 的经验,最好具有使用 Context API 的经验

⭐ 请务必查看资源主题以了解更多信息!

结果

通过阅读这篇文章将能够:

  • 要知道,有时候你并不需要 Redux 或 Context。
  • 了解 Context API 提供的具体内容,可以帮助您做出决策。
  • 了解何时可以使用 Context API 通过 Redux 进行状态管理。

国家管理:挑战

无论你编写的是哪种类型的应用程序,只要它最终会投入生产,或者包含一些复杂的功能,状态管理就绝非易事。在应用程序创建的初始阶段,需要经过深思熟虑才能做出“最佳”决策,而这通常与社区中许多人称之为“最佳”工具的工具有关。Redux 就是其中之一,自 2015 年以来一直广为使用,但这是否意味着你应该依赖 Redux 来解决任何未来可能出现的问题呢?并非如此。

就像你手里拿着锤子,不应该把所有问题都当钉子一样,任何需要进行状态管理的地方都不应该使用 Redux。这会导致效率低下,进而浪费时间。

理解了这一点之后,你应该知道很多人使用 Redux 来解决但实际上不应该解决的一些挑战:

  • 共享状态可以作为道具传递下去。
  • 管理表单状态 - 无需管理,因为表单状态不会影响整个应用程序。像 Formik 这样的库可以帮助你更好地做到这一点。
  • 在任何情况下使用它都会使你的处理方式变得复杂而不是更容易。

Context API:Redux 过多时的解决方案

Context API 并非新鲜事物,它已经存在一段时间了,但直到 React 16.3 版本才正式发布。引入 Context API 的目的可以说是简化深层嵌套组件之间的数据传递。它并非状态管理的解决方案,所有管理状态所需的逻辑都必须由您自行编写。更确切的说法是,Context API 不会为您管理状态。

这使得它非常灵活,您可以根据自己的需求进行调整,并轻松地通过嵌套的组件树传递状态。让我们实现一个简单的 UI,其中导航栏包含一个用户头像。它看起来有点像这样:

const UserContext = React.createContext()

const ProfilePicture = () => (
    <UserContext.Consumer>
        {(user) => <img width="56px" alt="pfp" src={user.pfp} />}
    </UserContext.Consumer>
)

const Nav = () => (
    <nav>
        <ProfilePicture />
    </nav>
)

class App extends React.Component {
    state = {
        user: {
            pfp: 'https://i.picsum.photos/id/50/200/300.jpg',
        },
    }

    render() {
        return (
            <div className="app">
                <UserContext.Provider value={this.state.user}>
                    <Nav />
                </UserContext.Provider>
            </div>
        )
    }
}

首先,你需要创建一个上下文,它主要包含两个属性ProviderConsumer,这两个属性的作用不言自明。提供者必须用来包装应用程序的主要部分,这些部分将使用它提供的值;而消费者则只是简单地使用该值并将其传递给需要它的组件。这样,在组件的嵌套子树中传递数据可以大大简化。

Redux:高级状态管理的解决方案

Redux 是一个状态管理库,它融合了 Flux 等库和 Elm 等语言的许多不同概念,旨在使状态管理尽可能轻松且易于测试。它通过遵循三个基本原则来实现这一点:

  1. 单一事实来源 - 拥有单一存储可以轻松调试和测试您的应用程序,否则难以实现的功能变得非常简单,因为您知道您的所有状态都在一个存储中,因此这是您的应用程序中唯一的事实来源。
  2. 状态应为只读 - 您应该只显示修改状态的意图,这可以防止您的 UI 或网络调用直接修改状态。此意图使用称为“操作”的普通对象来显示。这使得应用程序的调试和测试更加容易。
  3. 必须使用纯函数进行更改 - 实际的修改必须使用称为 Reducer 的纯函数完成。纯函数接受一个输入,并针对该输入返回相同的输出,并且没有副作用。Reducer 只是获取当前状态并返回下一个状态。

为了更好地掌握使用 Redux,让我们实现之前相同的示例,但使用 Redux 而不是 Context:

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { connect, Provider } from 'react-redux'

const initialState = {}

function reducer(state = initialState, action) {
    switch (action.type) {
        case 'SET_USER':
            return {
                ...state,
                user: action.user,
            }
        default:
            return state
    }
}

const store = createStore(reducer)

store.dispatch({
    type: 'SET_USER',
    user: {
        pfp: 'https://i.picsum.photos/id/50/200/300.jpg',
    },
})

const mapStateToProps = (state) => ({
    user: state.user,
})

const UserAvatar = connect(mapStateToProps)(({ user }) => (
    <img width="56px" alt="pfp" src={user.pfp} />
))

const Nav = () => (
    <nav>
        <UserAvatar />
    </nav>
)

const App = () => (
    <div className="app">
        <Nav />
    </div>
)

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.querySelector('#root')
)

如果您以前从未使用过 Redux,上面的代码示例可能会让您感到有些畏惧,但不必担心,它并没有什么神奇之处。Redux 在后台使用 Context 来将状态提供给许多不同的组件。开发人员常常以此为据,认为 Context API 最终会取代 Redux,但事实并非如此,也永远不会。Redux 不仅仅是对 Context 的简单包装,在我们讨论这一点之前,让我们先讨论一下 Redux 在上面示例中的工作原理。

首先,您必须使用 创建一个 store createStore(),此函数将使用 reducer 来修改 store 中存储的状态。reducer()是一个纯函数,它包含如何根据{ type: ...}分派到 store 的操作( 对象是一个操作)修改状态的逻辑。connect()是一个纯函数,它使所有相关组件都变为纯函数,以便它们仅在 store 的相关部分更新时才会重新渲染。

Redux 与 Context API:您应该使用哪一个?

如果你仔细阅读了前面两个主题,那么现在你应该很清楚何时应该使用 Context 而不是 Redux。然而,对于那些仍然难以做出决定的人来说,以下几点值得注意。

如果您使用 Redux,那么您可以使用:

  • Redux DevTools 扩展 - 此工具可让您轻松检查您的 store,并通过执行 diffing 和 tracing 等操作进行调试。您甚至可以重放已调度的操作。如果您觉得调试比较难,那么这个扩展值得一试。它可以作为软件包安装,也可以从扩展商店下载并在您的代码库中进行配置。
  • 中间件 - 中间件只是在每次调度操作时执行的函数。例如,Redux Thunk 是一个非常流行的中间件,它使异步调度操作成为可能,而 Redux Observable 则利用 RxJS 来实现副作用。
  • 可测试性——由于 Redux 的构建方式,使用 Redux 将使复杂应用程序的测试变得更容易。

最后,需要强调的是,即使在 React 生态系统中,Redux 也不会很快消亡或被弃用。无论如何,即使人们在 React 生态系统中停止使用它,它仍然会在 React 之外被使用。例如,React Native 是一个用于构建移动应用程序的框架,它使用 Redux 进行状态管理。虽然可以说 React Native 是 React 生态系统的一部分,但这是一个很好的例子,说明 Redux 即使在 React 之外仍将盛行。

值得一提的一些 Redux 替代品:

  • MobX——一个相对较新的库,解决了 Redux 的很多问题。
  • GraphQL - 一种数据驱动应用程序的解决方案,它使得前端不需要确切知道如何获取数据来获得正确的响应,从而实现了这一点。

关于 PixelPlex

PixelPlex 是一家软件开发公司,自 2007 年以来一直提供卓越的区块链、Web、游戏等众多开发服务。我们已交付超过 300 款产品,您的项目在我们手中绝对安全无虞。如果您想将梦想中的 SaaS 变成美好的现实,或者开始着手实现您一直渴望的那个想法,请访问我们的软件开发公司网站并联系我们!

概括

✅ ReactJS 是一个用于构建精美 UI 的前端库,其状态管理颇具挑战性,可以使用 Redux 之类的库来完成。✅
React 16.3 版本引入了 Context API,非常适合在深层嵌套的组件树之间传递数据。然而,它无法自动管理状态,您必须自行编写相关逻辑。✅
Redux 是一个状态管理库,适用于可测试性和可维护性至关重要的情况。Redux 提供了中间件的使用,可以扩展 Redux 的潜力。✅
Context API 并非 Redux 的替代品,也永远不会。是否使用 Context 替代 Redux,取决于您的具体情况。

资源

想了解更多?请查看以下链接:

  • Redux 与 React 的 Context API - Academind 的一篇文章,利用更多的代码示例来揭示 Redux 和 Context 之间的区别。
  • Awesome Redux - 大量有关 Redux 的资源,如果您想开始学习 Redux,那么您应该看看这个。
  • Formik - 虽然这不是您应该阅读以更好地理解 Redux 或 Context 的资源,但如果您在表单中的状态管理方面遇到困难,那么它是一个值得一试的库。
文章来源:https://dev.to/pixelplex/react-state-management-when-to-use-the-context-api-over-redux-5157
PREV
5 个值得一听的非科技播客
NEXT
帮助你的团队更加专注