我有一个包含许多子组件的 React 父组件(数千个 SVG 元素,重新渲染的成本很高)。子组件基于全局状态显示信息;某处是应该以特殊方式显示的那些子组件的列表。由于其他地方需要此列表,因此它不能是每个 child 的本地状态信息,因为它不是 child 的私有(private)信息。
遵循此处的建议:https://reactjs.org/docs/lifting-state-up.html我将状态提升到父组件。但是,一次只能改变一个 child ;例如,用户可能会点击一个 SVG 元素来调整它的显示属性(存储为 child 的 Prop )。但是,由于状态存储在父级中,因此在父级上调用 setState
会触发整个父级组件的昂贵重新渲染,包括其所有数千个子级,即使它们中的大多数没有改变了。
所以我不确定如何在 React 中正确地执行此操作并获得良好的性能。 (我找到了 forceUpdate
方法,以及许多永远不要使用它的警告。)我想我想做的是以某种方式更新 child 的 Prop ,但从文档中,唯一我可以看到父级更新单个子级的 Prop 的方式是调用父级的 render()
方法,这意味着它也重新渲染所有没有的 sibling '改变,这是我想避免的昂贵案例。
是否有某种方法可以让存储在父级或其他可以访问全局状态的点击处理程序更改此状态,并更新它影响的单个子组件的属性,然后只告诉那个子组件重新渲染?
抱歉,我没有包含任何源代码;这实际上是用 Dart 而不是 JS 编写的,但我认为问题出在底层 React 库的级别。
最佳答案
您必须使用 shouldComponentUpdate()
、React.PureComponent
或 React.memo()
(如果您使用的是 React > v16. 6.0 和功能组件)。你想要这样的东西:
父组件
class Parent extends Component {
state = {
color1: "red",
color2: "blue"
};
changeState = () =>
this.setState((state, props) => ({
color1: state.color1 === "red" ? "yellow" : "red",
color2: state.color2
}));
render() {
return (
<>
<Child color={this.state.color1} />
<Child color={this.state.color2} />
<button onClick={this.changeState}>Change State</button>
</>
);
}
}
每次单击 Change State
时,父级都会在红色和黄色之间切换 color1
状态属性。然后,您可以通过一些选项来优化您的应用。
shouldComponentUpdate()
class Child extends Component {
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.color !== this.props.color) return true;
return false;
}
render() {
return (
<div style={{ backgroundColor: this.props.color }}>I am a child</div>
);
}
}
React.PureComponent
class PureComponentChild extends React.PureComponent {
render() {
return (
<div style={{ backgroundColor: this.props.color }}>I am a child</div>
);
}
}
React.memo()
const FunctionalChild = React.memo(props =>
<div style={{ backgroundColor: props.color }}>I am a child</div>
);
有关更多信息,请查看 shouldComponentUpdate() , React.PureComponent和 React.memo()
关于reactjs - 基于全局状态变化重新渲染单个子组件而不重新渲染兄弟组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53563177/