React 中的上下文
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
ReactJS 中大家都在谈论的 Context 到底是什么?根据React 文档, “Context 提供了一种在组件树中传递数据的方法,而无需在每一层手动传递 props。”
所以我们可以看到,这是一种无需在每一层都使用 props 就能在组件树中传递数据的方法。是不是很神奇!因为它就像拥有全局变量,或者用 React 的术语来说,就像全局 props 一样。让我们举个例子,通过 React 的 Context 来更好地理解它。
这种功能的一个非常简单的用法是为你的 React 应用使用主题(深色主题/浅色主题)(注意:我们只能对那些不会经常改变的状态使用 Context)。因为主题应该传递给各个组件,以便在组件树中任意位置点击按钮时改变它们的外观。
如果我们使用常规的 props 来传递数据,可能会遇到问题,为什么呢?假设我们有一个应用程序,其中包含一个主组件、一个品牌组件和一个卡片部分,如下所示:
假设你在主组件中维护了一个状态,然后在卡片组件中使用它,那么你必须将状态从主组件传递到显示组件,然后再在卡片组件中获取。这是一种非常基础的结构,在结构复杂的 Web 应用中并不实用。 这时 React Context 就派上了用场。Context 为此提供了一种非常简单的结构。让我们来看看如何使用 Context:
- 您可能需要创建一个上下文,我们将使用它来存储全局属性,并且您可能需要在单独的组件中执行此操作(例如,这里创建了一个主题上下文)。
const ThemeContext = React.createContext();
- 然后,您需要创建一个 ContextProvider 组件,该组件将包装应用程序的所有组件,并且必须包含要传递给其中包装的每个组件的所有状态。
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const [backgroundColor, setBackgroundColor] = useState('bg-gray-100');
const [textColor, setTextColor] = useState('black');
const [cardsBackgroundColor, setCardsBackgroundColor] = useState('bg-white');
const toggleTheme = () => {
if (theme === 'light') {
window.localStorage.setItem('theme', 'dark');
setThemeColor('dark');
} else {
window.localStorage.setItem('theme', 'light');
setThemeColor('light');
}
};
return (
<ThemeContext.Provider
value={{
backgroundColor,
textColor,
cardsBackgroundColor,
toggleTheme,
theme,
}}
>
{children}
</ThemeContext.Provider>
);
};
- 因此,要使用 Context,我们实际上需要将所有内容都包裹在这些 Context 中,我们通常通过将整个 App 包裹在 ReactDOM.render() 中来实现这一点。
- 现在剩下的就是在需要的地方使用 Context 了,但在此之前,我们需要在所有需要使用 Context 的地方导入它。为了简化操作,您可以公开一个自定义钩子,以最大限度地减少 Context 的导入。
export const useContextTheme = () => {
return useContext(ThemeContext);
};
- 最后,现在我们要使用我们创建的上下文,为此我们需要在上一步中创建的自定义钩子,我们导入它,然后就可以随意使用它了!
导入上下文:
import { useContextTheme } from 'components/ThemeContext';
在组件内部使用:
const { toggleTheme, cardsBackgroundColor, theme } = useContextTheme();
