react上下文_揭秘React上下文

react上下文

What is context, and what does it do?

什么是上下文,它做什么?

Context allows you to set up a Provider component which allows Consumer components to subscribe to context changes. The consumer components do not need to be immediate children of the provider in order for the context to be passed down to them. The consumers can also be given access to methods that allow them to update the context (which in turn is broadcast to all other consumer components). This is useful when you have information that many parts of your app need to know. For information that only a few components need, other forms of state management, such as React Hooks or Class components, are likely a better fit.

上下文允许您设置提供者组件,该组件允许使用者组件订阅上下文更改。 消费者组件不必是提供者的直接子代,即可将上下文传递给他们。 消费者也可以被授予访问方法的权限,这些方法允许他们更新上下文(又将其广播到所有其他消费者组件)。 当您拥有应用程序的许多部分需要了解的信息时,此功能很有用。 对于仅需要几个组件的信息,其他形式的状态管理(例如React Hooks或Class组件)可能更合适。

Let’s walk through a simplified example where several components in our app are going to use a theme (“light” or “dark”) that a user can toggle. In this example we will:

让我们来看一个简化的示例,其中应用程序中的多个组件将使用用户可以切换的主题(“浅色”或“深色”)。 在此示例中,我们将:

  1. Create a Context Object using createContext

    使用createContext创建一个上下文对象
  2. Set up state and methods to be passed to our ThemeContext.Provider

    设置要传递给我们的ThemeContext.Provider的状态和方法
  3. Write a custom useTheme hook that will give our components access to the state and methods we passed to our ThemeContext.Provider

    编写一个自定义useTheme钩子,该钩子将使我们的组件可以访问传递给ThemeContext.Provider的状态和方法。
  4. Subscribe our components to ThemeContext using our custom hook

    使用我们的自定义钩子将我们的组件订阅到ThemeContext
An animated diagram showing the flow of information between Context and app components
ThemeContext in Action
实际运行中的ThemeContext

Let’s start by setting up our theme Context in ThemeProvider.js. The first thing we need to do is call React’s createContext with a defaultValue of null to create a Context object. Don’t worry too much about that null value for now; it will help us with error handling later. The main thing we want from this line is access to the Provider component that comes with every Context object.

让我们从在ThemeProvider.js中设置主题上下文开始。 我们需要做的第一件事是使用默认值null调用React的createContext来创建一个Context对象。 现在不必担心该空值。 它将帮助我们稍后进行错误处理。 我们从这行要得到的主要内容是访问每个Context对象随附的Provider组件。

I want to keep all of the state and methods related to my theme in this file and out of my main App.js, so I’m going to create a component called ThemeWrapper. In this component, I’ll give “theme” the default value “light” with the useState hook.

我想将与主题相关的所有状态和方法都保留在此文件中,并保留在主App.js中,因此我将创建一个名为ThemeWrapper的组件。 在此组件中,我将使用useState挂钩为“主题”提供默认值“ light”。

I’ll also create a function called toggleTheme that changes the theme from light to dark and vice versa.

我还将创建一个名为toggleTheme的函数,它将主题从浅色更改为深色,反之亦然。

Here I think it’s important to point out that my ThemeWrapper component itself is not the Provider, but I’m going to set it up to return the ThemeContext.Provider around props.children. Children is a special prop in React, and is effectively a placeholder for anything and everything between the opening and closing tags when the component is invoked. In our case, we want anything wrapped by our ThemeWrapper component to be rendered as a descendant of the ThemeContext.Provider so that those components can subscribe as a consumer if necessary.

在这里,我认为有必要指出,我的ThemeWrapper组件本身不是Provider,但我将对其进行设置以返回props.children周围的ThemeContext.Provider。 元素是React中的一种特殊道具,当组件被调用时,它实际上是占开始和结束标签之间的所有内容的占位符。 在我们的例子中,我们希望由ThemeWrapper组件包装的任何内容都呈现为ThemeContext.Provider的后代,以便那些组件可以在必要时作为使用者订阅。

What would they be subscribing to? Provider components (i.e. ThemeContext.Provider) accept a value prop that becomes available to consumer components. In our case, we want them to have access to the theme and the toggleTheme method.

他们将订阅什么? 提供程序组件(即ThemeContext.Provider)接受可供消费者组件使用的价值支持。 在我们的例子中,我们希望他们可以访问主题和toggleTheme方法。

One last step before we start using our context — let’s create a custom hook to get access to our ThemeContext.

开始使用上下文之前的最后一步-让我们创建一个自定义钩子,以访问我们的ThemeContext。

Essentially, our useTheme hook is going to check whether we’re trying to use the theme context within our ThemeContext.Provider (where it will have access to the values we set up above). If not (this is where the default null value from before comes into play), we’ll get a helpful error message. Our useTheme hook gets its real power from the default React hook useContext. Here, useContext is taking in our ThemeContext, which will give us access to the value and method we passed to our value prop in the ThemeContext.Provider. Whenever that value prop updates (i.e. when we change the theme using our toggleTheme method), this hook will trigger a re-render of the component using useContext — or in our case — using it by extension via useTheme.

本质上,我们的useTheme钩子将检查我们是否正在尝试在ThemeContext.Provider中使用主题上下文(它将在其中访问我们在上面设置的值)。 如果不是(这是之前的默认null值起作用的地方),我们将收到一条有用的错误消息。 我们的useTheme挂钩从默认的React挂钩useContext获得了真正的威力。 在这里,useContext接受了我们的ThemeContext,这将使我们能够访问传递给ThemeContext.Provider中的值属性的值和方法。 每当该值道具更新时(即,当我们使用toggleTheme方法更改主题时),此钩子都将使用useContext(或在我们的情况下)通过useTheme扩展使用它来触发组件的重新渲染。

Here is what the full ThemeProvider component looks like when we’re done:

完成后,这是完整的ThemeProvider组件的外观:

Let’s use our theme! This is the easy part 😁

让我们使用我们的主题! 这是容易的部分😁

Let’s say we have three components in our app:

假设我们的应用程序中包含三个组件:

  • A Header component that will change based on our theme

    标头组件将根据我们的主题而改变
  • An UnthemedComponent that won’t subscribe to our theme

    不会订阅我们主题的UnthemedComponent
  • A ThemeButton component that will toggle our theme and update accordingly

    一个ThemeButton组件,它将切换我们的主题并相应地更新

In order to give them access to our theme, we’ll wrap them in our ThemeWrapper component, making them the props.children of our ThemeContext.Provider.

为了使他们能够访问我们的主题,我们将它们包装在ThemeWrapper组件中,使它们成为ThemeContext.Provider的props.children。

From there, using our theme is as easy as importing our useTheme hook and calling it to get access to the current theme and toggleTheme method. Our ThemeButton will look something like this:

从那里开始,使用主题就像导入我们的useTheme钩子并调用它以访问当前主题和toggleTheme方法一样容易。 我们的ThemeButton将如下所示:

Our Header could look something like this:

我们的标题可能看起来像这样:

What about our UnthemedComponent? No need to do anything special — it won’t subscribe to changes in our theme unless we tell it to!

那我们的UnthemedComponent呢? 无需做任何特别的事情-除非我们告知,否则它不会同意我们主题的更改!

The finished demo app, switching from dark to light theme
Ta-da! 🎉
- 🎉

If we want more components to be subscribed to our theme, all we need to do is use our useTheme hook the same way!

如果我们想让更多组件订阅我们的主题,我们要做的就是以同样的方式使用我们的useTheme钩子!

Happy coding!

编码愉快!

翻译自: https://medium.com/the-innovation/demystifying-react-context-68ddb132e576

react上下文

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值