来自:www.digitalocean.com/community/t… 翻译:刘传君
2019年2月初,React引入了Hooks,作为一种重写你的组件的方式,让你的组件不需要class,从而变得更简单、更易管理。"useContext "是内置的Hooks之一,让功能组件可以轻松访问你的上下文。但在我们深入了解useContext之前,首先要介绍一些背景。
React Context API是一个简单、易懂的替代方案,可以让你在组件树的上下游进行属性钻探 "prop-drilling"。它不是在组件的几个层中传递本地数据,而是退一步创建全局状态,这对于需要在组件间共享的数据(如主题、认证、首选语言等数据)来说非常有用。
在Hooks出现之前,你需要使用基于类的组件。类组件可以管理本地状态,或者让你有能力将更新传递回你的状态管理。在基于类的组件中,你可以设置一个contextType或,并访问你从提供者那里传递下来的全局状态。但现在React已经转向轻量级的功能组件,如果你在这里,你可能也想这样做。
有了函数组件,我们就有了一个优雅、可读的组件。过去,函数组件很好用,因为它们不那么啰嗦,但它们的功能相当有限,只能接收属性,并根据这些属性渲染一个UI。有了Hooks,我们可以管理所有我们曾经使用过的基于类的组件。
示例Context
我们来看看如何使用useContext Hook来访问上下文。首先,为我们的例子做一个简单的存储。
const colors = {
blue: "#03619c",
yellow: "#8c8f03",
red: "#9c0312"
};
export const ColorContext = React.createContext(colors.blue);
提供 Context
然后,我们可以将我们的上下文提供给任何需要它的组件树。在这个例子中,我们为整个应用程序创建颜色,所以我们将把它包裹在我们的App中。
import { ColorContext } from "./ColorContext";
function App() {
return (
<ColorContext.Provider value={colors}>
<Home />
</ColorContext.Provider>
);
}
它为组件的其他部分(由Home组件代表)提供上下文。无论一个组件离Home组件有多远,只要它在组件树的某个地方,它就会收到ColorContext。在任何由我们的提供者包装的组件中,有多种方法可以消耗我们的上下文。
消费Context
我们可以使用,它在基于类和函数组件中都可以使用。在你的JSX中使用时,会是这样的样子。
return (
<ColorContext.Consumer>
{colors => <div style={colors.blue}>...</div>}
</ColorContext.Consumer>
);
然而,这样消费我们的上下文只能在返回块中使用,所以不能在你的 JSX 代码之外访问。当然,也有一些变通的方法,但不会是最理想的。
你可以给你的组件一个上下文类型:
MyComponent.contextType = ColorContext;
然后,你可以在你的组件中访问上下文:
let context = this.context;
这允许你在JSF之外访问你的上下文。或者相反,你可以放入静态contextType = ColorContext;。这对于基于类的组件来说非常好,因为它简化了如何将上下文带入你的组件中。但是,它在函数组件中是行不通的。
useContext
useContext和静态contextType = ColorContext是一样的,只不过它是针对函数组件的。在你的组件的顶部,你可以这样使用它。
import React, { useContext } from "react";
const MyComponent = () => {
const colors = useContext(ColorContext);
return <div style={{ backgroundColor: colors.blue }}>...</div>;
};
现在你的组件很简单,很容易阅读,也很容易测试。 确保这里你没有把ColorContext.Consumer传给useContext,我们在这里要的是整个上下文,而不是提供者或消费者。此外,你不再需要将你的 JSX 包裹在 Consumer 中,而是为了访问你的上下文,useContext 会为你做这些。
与所有新的Hooks一样,它们不一定是什么新东西。它们遵循的是我们之前学习过的React模式。有关Hooks的更多信息,请参见官方文档。