import React, { useReducer, useEffect ,Component} from "react";
import ReactDOM from "react-dom";
const AppContext = React.createContext();
import React from "react";
const withRandomColors = WrappedComponent => {
return class RandomColors extends React.Component {
constructor() {
super();
this.randomColors = [
"red",
"blue",
"green",
"cyan",
"lavender",
"skyblue",
"orange",
"pink",
"yellow"
];
}
getRandomColors() {
const num = Math.floor(Math.random() * 10) % 9;
return this.randomColors[num];
}
render() {
console.log("Rerendering wrapper Component");
return <WrappedComponent randomColor={this.getRandomColors()} />;
}
};
};
class Number extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {}
render() {
console.log("rendering Number Component");
return (
<AppContext.Consumer>
{({ number }) => {
return (
<div style={{ backgroundColor: `${this.props.randomColor}` }}>
{number} <br />
</div>
);
}}
</AppContext.Consumer>
);
}
}
class Text extends React.Component {
constructor(props) {
super(props);
}
render() {
console.log("rendering Text Component");
return (
<AppContext.Consumer>
{({ text }) => (
<div style={{ backgroundColor: `${this.props.randomColor}` }}>
{text} <br />
</div>
)}
</AppContext.Consumer>
);
}
}
const WrappedText=withRandomColors(Text);
const WrappedNumber=withRandomColors(Number);
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() {
console.log("rendering app")
return (
<AppContext.Provider value={this.state}>
<div>
<h1>Welcome to React</h1>
<WrappedNumber />
<WrappedText />
<button onClick={this.updateNumber}>Change Number </button>
</div>
</AppContext.Provider>
);
}
}
ReactDOM.render(
<App />,
mountNode
);
当单击 ChangeNumber 按钮时,控制台显示
rendering app
Rerendering wrapper Component
Rerendering Number Component
Rerendering wrapper Component
Rerendering Text Component
数字和文本的背景颜色都会发生变化。
React 上下文应该只为提供者重新渲染消费者,对吧?为什么它要重新渲染 Provider 的所有子级?
我预计,一旦单击“更改数字”按钮,只有数字更改会保持数字和文本的背景颜色相同,并低于控制台的输出,因为只有消费者才应该重新渲染而不是文本和数字组件。
rendering app
我错过了什么?
我从 sandbox 获取了代码
最佳答案
当您更新 App 组件中的状态时,
WrappedNumber
和 WrappedText
会重新渲染,因为在 Virtual DOM 中,它们与 Provider 位于同一层次结构中,并且当父组件组件更新子组件也会更新。
为了避免它们重新渲染,您可以将它们作为应用程序的子项提供,例如
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() {
console.log("rendering app")
return (
<AppContext.Provider value={this.state}>
<div>
<h1>Welcome to React</h1>
{this.props.children}
<button onClick={this.updateNumber}>Change Number </button>
</div>
</AppContext.Provider>
);
}
}
ReactDOM.render(
<App >
<WrappedNumber />
<WrappedText />
</App>,
mountNode
);
关于javascript - react 上下文重新渲染提供者的每个 child ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61599315/