React Context 指南
什么是 React Context 🤔?
React Context提供了一种在组件树中传递数据的方法,而无需props
手动将数据传递到每一层。在 React 中,数据通常作为属性从父组件传递到其子组件。
Context 对于 React 组件子树来说就像一个全局对象🌐。
Context 解决了什么问题😟?
- 在 React 应用程序中,父组件将数据传递给子组件,但是当该数据要由多层子组件使用而不是由该父组件的直属子组件使用时,就会出现问题。
让我们看一下下面的图表📈。
Component A
显然是具有直接子组件 B、C 的主要父组件。这些组件可以从中接收参数component A
并将数据传递给子组件,但是如果Component E
需要从中获取数据Component A
而不需要该数据,Component B
那么将数据传递给Component B
就变得多余了。
道具钻取,这个术语用来描述当你通过不需要它的组件将道具向下传递到嵌套组件的多个级别时的情况。
这就是React context 的好处——它提供了一种很酷的方式😎,让数据可以随时供 React 应用程序中的每个子组件使用。
我们如何使用 Context 😕?
据我们所知,React 上下文允许我们在 React 应用程序中需要的任何组件中传递和使用(消耗props
)数据,而无需使用。
使用新的 React Context API 取决于four
主要步骤:
🔸 使用该方法创建 Context createContext
。此函数返回一个包含Provider和Consumer 的对象。
import React from 'react';
const AuthContext = React.createContext();
🔸 接下来,使用Provider 组件包裹父/主组件。
🔸 将子组件包装在Provider 组件中,并使其接受一个名为 的 prop value
。value
可以是任何值!
<AuthContext.Provider value={value}>
<Demo />
</AuthContext.Provider>
🔸在组件树中提供者 (Provider) 下方的任何位置使用消费者 (Consumer) 组件来获取状态的子集。
function Demo() {
return (
<AuthContext.Consumer>
{value => <h1>{value}</h1>}
</AuthContext.Consumer>
);
}
📌让我们看完整的例子:
import React from 'react';
export const AuthContext = React.createContext();
export default function App() {
return (
<AuthContext.Provider value="Happy">
<Demo />
</AuthContext.Provider>
)
}
function Demo() {
return (
<AuthContext.Consumer>
{value => <h1>{value}</h1>} /* prints happy */
</AuthContext.Consumer>
);
}
在我们的App 组件上方,我们使用创建上下文React.createContext()
并将结果放入变量中AuthContext
。
- 在几乎所有情况下,您都会希望像我们在这里所做的那样将其导出,因为您的组件将位于另一个文件中。
请注意,当我们调用 React.createContext() 时,我们可以将初始值传递给我们的值 prop。
- 创建的上下文是一个具有两个属性的对象:
Provider
和Consumer
,它们都是组件。
需要记下 Provider 实际做的事情✍️:
➡️ 它包含一个单一的 javascript值,该值可以是任何东西:数组、函数或对象。
➡️ 它不会导致其子级重新渲染:上下文提供者的直接子级不会在提供者每次渲染时重新渲染,但消费者会。
此规则仅适用于由提供者内部(state)引起的重新渲染,但如果其父级重新渲染 (props),则提供者的子级也会重新渲染。➡️当上下文值改变时,所有订阅者都会重新渲染。
-
在我们的App 组件中,我们使用 AuthContext。具体来说
AuthContext.Provider
,为了将我们的value
传递给 App 中的每个组件,我们将Provider 组件包装在其周围,在本例中为Demo
。 -
在 上
AuthContext.Provider
,我们放置了想要在整个组件树中传递的值。我们将其设置为value
prop 的值。(这里是Happy)。 -
在 中
Demo
,或者任何我们想要使用上下文中提供的内容的地方,我们都使用消费者组件:AuthContext.Consumer
要使用传递的值,我们使用所谓的渲染道具模式。
它只是消费者组件以 的形式提供给我们的一个函数prop
。作为该函数的回报,我们可以返回并使用该value
。
使用上下文的另一种方法是使用useContext hook。
📌 以下是使用useContext 的相同示例:
import React from 'react';
export const AuthContext = React.createContext();
export default function App() {
return (
<AuthContext.Provider value="Happy">
<Demo />
</AuthContext.Provider>
)
}
function Demo() {
const value = React.useContext(AuthContext);
return <h1>{value}</h1>;
}
useContext接受上下文类型作为参数,并返回距离最近的该类型提供程序的上下文值。如果不存在该提供程序,则返回默认的上下文值。
应用程序的性能会受到影响吗?
🔹简而言之,如果您的提供程序做了很多工作,那么您的应用程序的性能将急剧下降,例如,拥有一个结合了许多单独值的值,您将拥有同一提供程序的许多消费者,并且他们都会重新渲染。
🔹 当提供者的包装器由于内部原因(可能是状态)而重新渲染时,其子组件不会重新渲染,只有消费者会重新渲染。这就像提供者的值直接从提供者传送到消费者,忽略了中间的一切。
🔹 因此,拥有多个上下文和提供者是完全可以的。
Redux 与 context API 有何不同?
如您所见,所涉及的概念实际上与Redux没有太大区别。
那么context 会取代 redux 吗?
答案是否定的。
Redux 不仅是一种传递 props(传送 props)的方式,它还支持持久化、中间件,以及许多其他优势。
我建议使用Redux进行复杂的全局状态管理,并使用Context进行 props 的传递。
由于本文并非旨在讨论 redux,因此我将放弃一些有用的资源来阅读有关此比较的更多信息👇。
- 在StackOverflow上回答。
- Dan 的帖子关于你可能不需要 Redux。
在本文中,我们探讨了如何轻松地使用 React Context 而不是传递 props 来实现组件间数据共享🚢。
根据你的使用场景,你可能更喜欢使用简单的props、React Context甚至像Redux这样的第三方库来实现组件间数据共享。
继续写代码 😉。感谢阅读💖。
欢迎随时通过Twitter与我们联系:)
文章来源:https://dev.to/adyasha8105/a-guide-to-react-context-46oo