1、介绍
useContext 是 React hooks 三个最根底的 hook 函数之一。
const value = useContext(MyContext);
useContext 接管一个 context 对象(React.createContext 的返回值)并返回该 context 的以后值。
以后的 context 值由下层组件中距离以后组件最近的 <MyContext.Provider> 的 value prop 决定。当组件下层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重渲染,并应用最新传递给 MyContext provider 的 context value 值。
即便先人应用 React.memo 或 shouldComponentUpdate,也会在组件自身应用 useContext 时从新渲染。调用了 useContext 的组件总会在 context 值变动时从新渲染。如果重渲染组件的开销较大,你能够 通过应用 memoization 来优化。
留神:useContext(MyContext) 只是让你可能读取 context 的值以及订阅 context 的变动。你依然须要在下层组件树中应用 <MyContext.Provider> 来为上层组件提供 context。
2、Context 的应用
- React.createContext
const MyContext = React.createContext(defaultValue);
创立一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离本身最近的那个匹配的 Provider 中读取到以后的 context 值。
只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会失效。这有助于在不应用 Provider 包装组件的状况下对组件进行测试。留神:将 undefined 传递给 Provider 的 value 时,生产组件的 defaultValue 不会失效。
- React.Provider
<MyContext.Provider value={/* 某个值 */}>
每个 Context 对象都会返回一个 Provider React 组件,它容许生产组件订阅 context 的变动。
Provider 接管一个 value 属性,传递给生产组件。一个 Provider 能够和多个生产组件有对应关系。多个 Provider 也能够嵌套应用,里层的会笼罩外层的数据。
当 Provider 的 value 值发生变化时,它外部的所有生产组件都会从新渲染。Provider 及其外部 consumer 组件都不受制于 shouldComponentUpdate 函数,因而当生产组件在其先人组件退出更新的状况下也能更新。
通过新旧值检测来确定变动,应用了与 Object.is 雷同的算法。
- React.Consumer
<MyContext.Consumer>
{value => /* 基于 context 值进行渲染 */}
</MyContext.Consumer>
这里,React 组件也能够订阅到 context 变更。这能让你在函数式组件中实现订阅 context。
3、useContext
Context 设计目标是为了共享那些对于一个组件树而言是“全局”的数据,例如以后认证的用户、主题或首选语言。
const ThemeContext = React.createContext(1);
export function App() {const [value, setValue] = useState(1)
return (<ThemeContext.Provider value={value}>
<button onClick={() => setValue(() => value + 1)}>App</button>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {console.log('Toolbar');
return (
<div>
<ThemedButton />
</div>
);
}
const ThemedButton = () => {const theme = useContext(ThemeContext);
console.log('themebutton', theme);
return (
<div>
<button>{theme}</button>
</div>
)
}