更新上下文值不会触发提供程序(provider)的所有子组件重新渲染,只有从Consumer内部呈现的组件才会重新渲染。因此,在您的情况下,尽管数字(number)组件包含了Consumer,但Number组件不会重新呈现,而只是在Consumer中的渲染函数中进行更改,因此当上下文更新时值就会更改。这种方式非常高效,因为它不会触发其所有子元素的重新渲染。
所有使用该提供程序(provider)的消费者将经历一个更新周期,但它们是否重新渲染由React虚拟DOM比较决定。可以在此sandbox中的控制台中查看此演示。
编辑
需要确保组件被呈现为ContextProvider组件的子元素,并向其传递处理程序,而不是内联呈现并更新ContextProvider的状态,因为这将触发ContextProvider
内所有组件的重新呈现。
高性能用法
App.js
constructor() {
super();
this.state = {
number: Math.random() * 100,
text: "testing context api"
updateNumber: this.updateNumber,
};
}
render() {
return (
<AppContext.Provider
value={this.state}
>
{this.props.children}
</AppContext.Provider>
);
}
index.js
class Data extends React.Component {
render() {
return (
<div>
<h1>Welcome to React</h1>
<Number />
<Text />
<TestComp />
<AppContext.Consumer>
{({ updateNumber }) => (
<button onClick={updateNumber}>Change Number </button>
)}
</AppContext.Consumer>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App>
<Data />
</App>,
rootElement
);
性能较差的使用方式
App.js
class App extends Component {
constructor() {
super();
this.state = {
number: Math.random() * 100,
text: "testing context api"
};
}
updateNumber = () => {
const randomNumber = Math.random() * 100;
this.setState({ number: randomNumber });
};
render() {
return (
<AppContext.Provider value={this.state}>
<div>
<h1>Welcome to React</h1>
<Number />
<Text />
<TestComp />
<button onClick={this.updateNumber}>Change Number </button>
</div>
</AppContext.Provider>
);
}
}
Provider
的所有子组件在value
更改时不会全部重新渲染,但我相信消费者组件的所有子组件仍将重新渲染? - darKnight