网站首页 > 网页设计教程 > Javascript教程 > react中context是什么

react中context是什么

  • 作者:互联网
  • 时间:2022-07-06 09:49:34

在react中,context是一个无需为每层组件手动添加props就能在组件树之间进行数据传递的方法;context提供了一种在组件之间共享指定值的方式,而且不必显式的通过组件树的逐层传递props。

本教程操作环境:Windows10系统、re***17.0.1版、Dell G3电脑。

react中context是什么

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。

Context 什么时候用?

Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。举个例子,在下面的代码中,我们通过一个 “theme” 属性手动调整一个按钮组件的样式

class App extends Re***.Component { render() { return ; }}function Toolbar(props) { // Toolbar 组件接受一个额外的“theme”属性,然后传递给 ThemedButton 组件。 // 如果应用中每一个单独的按钮都需要知道 theme 的值,这会是件很麻烦的事, // 因为必须将这个值层层传递所有组件。 return (

pr***.theme} />

);}class ThemedButton extends Re***.Component { render() { return )} Co***xt.Consumer> );}export default ThemeTogglerButton;

app.js

import { ThemeContext, themes } from './theme-context';import ThemeTogglerButton from './theme-toggler-button';class App extends Re***.Component { constructor(props) { super(props); th***toggleTheme = () => { th***setState(state => ({ theme: st***.theme === th***s.dark ? th***s.light : th***s.dark, })); }; // State 也包含了更新函数,因此它会被传递进 context provider。 th***state = { theme: th***s.light, toggleTheme: th***toggleTheme, // 定义更新函数,通过context方式向下传递 }; } render() { // 整个 state 都被传递进 provider return ( <Th***Co***xt.Provider value={th***state}> Th***Co***xt.Provider> ); }}function Content() { return (

);}Re***DOM.render(, do***ent.root);

消费多个 Context

为了确保 context 快速进行重渲染,React 需要使每一个 consumers 组件的 context 在组件树中成为一个单独的节点

// Theme context,默认的 theme 是 "light" 值const ThemeContext = Re***.createContext('light');// 用户登录 contextconst UserContext = Re***.createContext({ name: 'Guest',});class App extends Re***.Component { render() { const { signedInUser, theme } = th***props; // 提供初始 context 值的 App 组件 return ( <Th***Co***xt.Provider value={theme}> Co***xt.Provider value={signedInUser}> Co***xt.Provider> Th***Co***xt.Provider> ); }}function Layout() { return (

);}// 一个组件可能会消费多个 contextfunction Content() { return ( Co***xt.Consumer> {theme => ( Co***xt.Consumer> {user => ( )} Co***xt.Consumer> )} Co***xt.Consumer> );}

如果两个或者更多的 context 值经常被一起使用,那你可能要考虑一下另外创建你自己的渲染组件,以提供这些值。

注意事项

因为 context 会使用参考标识(reference identity)来决定何时进行渲染,这里可能会有一些陷阱,当 provider 的父组件进行重渲染时,可能会在 consumers 组件中触发意外的渲染。举个例子,当每一次 Provider 重渲染时,以下的代码会重渲染所有下面的 consumers 组件,因为 value 属性总是被赋值为新的对象

class App extends Re***.Component { render() { return ( Co***xt.Provider value={{something: 'something'}}> Co***xt.Provider> ); }}

为了防止这种情况,将 value 状态提升到父节点的 state 里

class App extends Re***.Component { constructor(props) { super(props); // 多次渲染,state 会被保留,当value不变时,下面的 consumers 组件不会重新渲染 th***state = { value: {something: 'something'}, }; } render() { return ( th***state.value}> ); }}