根据全局状态变化重新渲染单个子组件,而无需重新渲染同级

时间:2018-11-30 18:44:36

标签: reactjs

我有一个带有许多子组件的React父组件(成千上万的SVG元素重新渲染很昂贵)。子组件根据全局状态显示信息。某处是应该以特殊方式显示的那些子组件的列表。由于此列表在其他位置需要使用,因此它不能是每个孩子的本地状态信息,因为它不是孩子专用的。

遵循以下建议:https://reactjs.org/docs/lifting-state-up.html我将状态提升到父组件。但是,一次只能改变一个孩子。例如,用户可以单击SVG元素以调整其显示属性(存储为孩子的道具)。但是,由于状态存储在父级中,因此在父级上调用setState会触发整个父级组件(包括其数千个子级)的昂贵重新呈现,即使其中大多数未更改。 / p>

所以我不确定如何在React中正确执行此操作并获得良好的性能。 (我发现了forceUpdate方法以及许多从未使用过的警告。)我想我想做的就是以某种方式更新孩子的道具,但是从文档中,我唯一的方法是请参见让父母更新单个孩子的道具,请参见要调用父母的render()方法,这意味着它还会重新渲染所有未更改的兄弟姐妹,这就是我想避免昂贵的情况。

是否有某种方式可以将单击处理程序存储在父级或其他位置中,并且可以访问全局状态,以更改此状态,并更新受影响的单个子组件的道具,然后仅告诉该子组件重新渲染?

对不起,我没有任何源代码。这实际上是用Dart而不是JS编写的,但是我认为问题出在底层React库的级别。

1 个答案:

答案 0 :(得分:3)

您必须使用shouldComponentUpdate()React.PureComponentReact.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.PureComponentReact.memo()