我有一个带有许多子组件的React父组件(成千上万的SVG元素重新渲染很昂贵)。子组件根据全局状态显示信息。某处是应该以特殊方式显示的那些子组件的列表。由于此列表在其他位置需要使用,因此它不能是每个孩子的本地状态信息,因为它不是孩子专用的。
遵循以下建议:https://reactjs.org/docs/lifting-state-up.html我将状态提升到父组件。但是,一次只能改变一个孩子。例如,用户可以单击SVG元素以调整其显示属性(存储为孩子的道具)。但是,由于状态存储在父级中,因此在父级上调用setState
会触发整个父级组件(包括其数千个子级)的昂贵重新呈现,即使其中大多数未更改。 / p>
所以我不确定如何在React中正确执行此操作并获得良好的性能。 (我发现了forceUpdate
方法以及许多从未使用过的警告。)我想我想做的就是以某种方式更新孩子的道具,但是从文档中,我唯一的方法是请参见让父母更新单个孩子的道具,请参见要调用父母的render()
方法,这意味着它还会重新渲染所有未更改的兄弟姐妹,这就是我想避免昂贵的情况。
是否有某种方式可以将单击处理程序存储在父级或其他位置中,并且可以访问全局状态,以更改此状态,并更新受影响的单个子组件的道具,然后仅告诉该子组件重新渲染?
对不起,我没有任何源代码。这实际上是用Dart而不是JS编写的,但是我认为问题出在底层React库的级别。
答案 0 :(得分:3)
您必须使用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>
</>
);
}
}
每次单击color1
时,父级都会在红色和黄色之间切换Change State
状态属性。然后,您可以选择一些选项来优化您的应用。
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()