使用Context简单传参例子
解决父子组件多层嵌套传参,中间不用通过props传值
import React, { useContext } from "react";
// 参数对象
const param = { title: "星期四" };
// 创建一个 Context 对象
// const MyContext = React.createContext(defaultValue);
// 当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。
// 只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。
const ParentContext = React.createContext({});
// 子组件2
function Children2() {
// 接收一个 context 对象(React.createContext的返回值)并返回该 context 的当前值
const parentParam: any = useContext(ParentContext);
return (
<div className="back2 bor">
<p>子组件2</p>
接收到的值:{parentParam.title}
</div>
);
}
//子组件1
function Children1() {
return (
<div className="back1 bor">
<p>子组件1</p>
<Children2 />
</div>
);
}
// 父组件
const ParentPage: React.FC = () => {
return (
<div className="back bor">
{/* <MyContext.Provider value={某个值 }></MyContext.Provider> */}
{/* Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。 */}
<ParentContext.Provider value={param}>
<p>父组件</p>
<Children1 />
</ParentContext.Provider>
</div>
);
};
export default ParentPage;
// 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。从 Provider 到其内部 consumer 组件(包括 .contextType 和 useContext)的传播不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件跳过更新的情况下也能更新。
Context API
React.createContext:创建一个 Context 对象。
Context.Provider:每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。
Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。
注意事项:因为 context 会根据引用标识来决定何时进行渲染(本质上是 value 属性值的浅比较),所以这里可能存在一些陷阱,当 provider 的父组件进行重渲染时,可能会在 consumers 组件中触发意外的渲染。举个例子,当每一次 Provider 重渲染时,由于 value 属性总是被赋值为新的对象,以下的代码会重新渲染下面所有的 consumers 组件:
class App extends React.Component {
render() {
return (
<MyContext.Provider value={{something: 'something'}}>
<Toolbar />
</MyContext.Provider>
);
}
}
为了防止这种情况,将 value 状态提升到父节点的 state 里:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: {something: 'something'},
};
}
render() {
return (
<MyContext.Provider value={this.state.value}>
<Toolbar />
</MyContext.Provider>
);
}
}
Class.contextType:
挂载在 class 上的 contextType 属性可以赋值为由 React.createContext() 创建的 Context 对象。此属性可以让你使用 this.context 来获取最近 Context 上的值。你可以在任何生命周期中访问到它,包括 render 函数中。
Context.Consumer:
<MyContext.Consumer>
{value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
一个 React 组件可以订阅 context 的变更,此组件可以让你在函数式组件中可以订阅 context。
这种方法需要一个函数作为子元素(function as a child)。这个函数接收当前的 context 值,并返回一个 React 节点。传递给函数的 value 值等价于组件树上方离这个 context 最近的 Provider 提供的 value 值。如果没有对应的 Provider,value 参数等同于传递给 createContext() 的 defaultValue。
Context.displayName:context 对象接受一个名为 displayName 的 property,类型为字符串。React DevTools 使用该字符串来确定 context 要显示的内容。