您已经创建了一个提供程序,它使其value 可供树中的每个孩子使用。但是,任何想要使用该值的孩子都需要使用它。
如何使用上下文的模式对于类组件 VS 是不同的。函数组件,但基本原理是一样的:你需要告诉你的子组件如何从上下文中获取主题值。
从函数组件中使用上下文
对于函数组件,最简单的方法是使用useContext 钩子(直接从the hooks docs) 复制的示例:
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
带有自定义钩子的有用模式
上述方法可行,但是有一个非常好的模式,您可以将消费者包装在一个自定义挂钩中,您可以称之为useTheme(我第一次看到这种模式here)。
// Step 1
const ThemeContext = React.createContext(undefined)
// Step 2
function ThemeProvider({children}) {
return (
<ThemeContext.Provider value={light}>
{children}
</ThemeContext.Provider>
)
}
// Step 3
function useTheme() {
const context = React.useContext(ThemeContext)
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider')
}
return context
}
export {ThemeProvider, useTheme}
第 1 步 - 创建上下文。你已经在你的例子中做到了。
第 2 步 - 创建提供程序。您在“我的应用”中使用了提供程序。
第 3 步 - 这是新功能。它创建一个自定义钩子,检查提供者是否可访问(如果不是,则抛出错误),然后从提供者返回值。
然后你像这样使用钩子:
function ThemedButton() {
const theme = useTheme()
return <Text color={theme.textColor}>Some text</Text>
}
这种模式有几个好处:
- 您只需要在使用主题的组件中导入钩子
useTheme。如果直接使用useContext,则需要导入上下文和useContext钩子。
- 如果您不小心尝试在组件树中无权访问提供程序的某个位置使用
useTheme,throw new Error('...') 行会向您发出警告。
使用类组件使用上下文
带有类组件的示例有点长且更细微,因此我建议使用the docs 了解如何执行此操作的详细信息。但是,一种方法是这样的:
<ThemeContext.Consumer>
{value => <ThemedButton theme={value} />
</ThemeContext.Consumer>