在 React 中,有时候组件间需要共享一些数据,这些数据可能会存在嵌套多层的关系中。一种常见的解决方案是通过 props 将数据从祖先组件传递给后代组件。但是,如果孙子、曾孙等后代组件需要访问这些数据,可能也需要一层层地将数据传递下去,这样就显得很麻烦。
为了解决这个问题,React 提供了 Context API。在 React 中,Context 允许我们将数据沿着组件树传递下去,不必显式地将数据层层传递给每个组件。
创建 Context
我们可以使用 React.createContext
方法来创建一个 Context 对象。
const MyContext = React.createContext(defaultValue);
这里的 defaultValue
是一个可选的值,表示当没有任何一个祖先组件提供了相应的 Context
时,该组件会使用 defaultValue
做为默认值。这个默认值也可以通过 Provider
的 value
属性来覆盖。
使用 Context
使用 Context 的两种方式:
Consumer
:用于在函数式组件中使用 Context。useContext
:在函数式组件中使用 Context,使用 Hooks。
Consumer
在类似于以下的组件树中,我们需要将 username
数据从 User
组件传递到 Welcome
组件。
<App> <User> <Welcome /> </User> </App>
创建 Context
首先,我们需要创建一个 Context:
const UserContext = React.createContext("Guest");
这里的 defaultValue
是一个字符串 "Guest"。
提供 Context
接下来,在 User
组件中,我们需要将 username
提供给 UserContext.Provider
。
<Header /> <UserContext.Provider value={this.state.username}> <Welcome /> </UserContext.Provider>
这里我们使用 this.state.username
作为 value
,因为 User
组件中有一个叫做 username
的 state。
消费 Context
最后,在 Welcome
组件中,我们可以通过 UserContext.Consumer
来消费 UserContext
中的 username
。
function Welcome() { return ( <UserContext.Consumer> {username => ( <h2>Welcome, {username}!</h2> )} </UserContext.Consumer> ); }
useContext
使用 useContext
,我们可以更简洁地在函数式组件中使用 Context。
const username = useContext(UserContext);
上述代码中,username
获得了 UserContext
中的数据。需要注意的是,useContext
必须在函数式组件中使用。
共享多个数据
如果需要共享多个数据,在 Provider
中传入一个包含所有数据的对象即可。
<UserContext.Provider value={{username: this.state.username, theme: this.state.theme}}> <Welcome /> </UserContext.Provider>
在 Consumer
或 useContext
中,可以像下面这样使用多个数据:
const { username, theme } = useContext(UserContext);
示例代码
import React, { createContext, useState, useContext } from "react"; const UserContext = createContext("Guest"); const ThemeContext = createContext("light"); function App() { const [username, setUsername] = useState("John"); const [theme, setTheme] = useState("light"); return ( <div> <UserContext.Provider value={username}> <ThemeContext.Provider value={theme}> <Header /> <Welcome /> </ThemeContext.Provider> </UserContext.Provider> <button onClick={() => setUsername("Jane")}>Change User</button> <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>Toggle Theme</button> </div> ); } function Header() { return ( <ThemeContext.Consumer> {theme => ( <header style={{ backgroundColor: theme }}> <h1>My App</h1> </header> )} </ThemeContext.Consumer> ); } function Welcome() { const username = useContext(UserContext); const theme = useContext(ThemeContext); return ( <div style={{ backgroundColor: theme }}> <h2>Welcome, {username}!</h2> </div> ); }
总结
使用 Context 可以帮助我们在 React 中共享数据,特别是当数据需要沿组件树传递时。通过创建 Context 和在 Provider 中提供数据,可以在 Consumer 或 useContext 中访问数据。Context 的 API 是 React 提供的,使用上比较方便,但需要注意一些细节。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b4a6c3add4f0e0ffd89442