javascript - 新的 React Context API 会触发重新渲染吗?
问题描述
我一直在尝试理解新的 React Context API 并正在使用它。我只是想检查一个简单的案例 - 更新到 Provider 的数据时所有重新呈现的内容。
在 Codesandbox 上查看这个小例子
所以,在我的例子中,我有一个App
组件——它的状态是这样的——
this.state = {
number - A random number
text - A static text
}
我从这里创建了一个新的 React 上下文,包含number
和text
from state,并将值传递给两个 ConsumersNumber
和Text
.
所以我的假设是如果随机数更新,它将改变上下文并且两个组件都应该触发重新渲染。
但实际上,值正在更新,但没有发生重新渲染。
所以,我的问题——
是否更新到不通过通常的重新渲染传播的上下文?因为当上下文发生变化时,我看不到我的日志/颜色变化。
该提供者的所有消费者是否都已更新?
解决方案
是否更新到不通过通常的重新渲染传播的上下文?因为当上下文发生变化时,我看不到我的日志/颜色变化。
对上下文值的更新不会触发提供者的所有子项的重新呈现,而只会触发从消费者内部呈现的组件,因此在您的情况下,尽管数字组件包含消费者,但数字组件不会重新呈现,而只是 Consumer 中的 render 函数,因此值会在上下文更新时发生变化。通过这种方式,它的性能非常好,因为它不会触发所有子级的重新渲染。
该提供者的所有消费者是否都已更新?
该 Provider 的所有消费者都将经历一个更新周期,但他们是否重新渲染取决于 react 虚拟 DOM 比较。您可以在此沙盒的控制台中看到一个演示
编辑
您需要确保将组件呈现为 ContextProvider 组件的子组件,并且您将处理程序传递给它,而不是内联呈现它们并更新 ContextProvider 的状态,因为这将触发内部所有组件的重新呈现这ContextProvider
高性能使用
应用程序.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
);
更少的性能使用
应用程序.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>
);
}
}
推荐阅读
- visual-studio-debugging - Concord(VS调试器)方法链接问题
- amazon-web-services - AWS EC2 使用私有 IP 神奇地路由到 S3
- switch-statement - 在 for 循环中使用带有 5 个案例的 switch 语句。如何将案例语句保存到数据库中?
- c# - 如何让精灵在单人游戏中从一个位置到鼠标点击进行可见的移动?
- video-streaming - 输入少量输入样本后,英特尔图形硬件 H264 MFT ProcessInput 调用失败,同样适用于 Nvidia 硬件 MFT
- java - 如何在 Mac 中的 java 中恢复使用 File.delete() 方法删除的文件
- ruby-on-rails - “best_in_place” gem 是否适用于 Rails 6?
- c++ - 将函数传递给动态链接库
- ios - UISegmentedControl iOS 13 一起改变 UIControlStateSelected 和 UIControlStateHighlighted 的颜色
- matlab - 三维最小均方