Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但此种用法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。
简单来说就是
App是父组件 Toolbar是子组件 ThemedButto是孙组件 对比如下
Context API
React.createContext
创建一个 Context 对象。
只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue
参数才会生效。此默认值有助于在不使用 Provider 包装组件的情况下对组件进行测试。注意:将 undefined
传递给 Provider 的 value 时,消费组件的 defaultValue
不会生效。
当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider
中读取到当前的 context 值。
Context.Provider
每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。
Provider 接收一个 value
属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。
当 Provider 的 value
值发生变化时,它内部的所有消费组件都会重新渲染。从 Provider 到其内部 consumer 组件(包括 .contextType 和 useContext)的传播不受制于 shouldComponentUpdate
函数,因此当 consumer 组件在其祖先组件跳过更新的情况下也能更新。
父组件:
子组件:
通过给父组件绑定Context对象将them数据 从App父组件直接传递到 ThemeButton孙组件中
useContext
接收一个上下文对象(React.createContext的返回值,可以理解为全局比变量)并返回该上下文的当前值。当前的上下文值由上层组件中距离当前组件最近的属性<MyContext.Provider>决定value。
当上层最近<MyContext.Provider>更新时,该 Hook 会触发重渲染,并使用最新提交给MyContext提供者的上下文value。即使祖先使用React.memo或使用组件,也会在其自身shouldComponentUpdate组件使用useContext时重新渲染。
孙组件:
注意:
Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。请谨慎使用,因为这会使得组件的复用性变差。