更改父状态时如何防止子组件重新加载

时间:2018-06-22 00:51:28

标签: javascript reactjs

在某些情况下,父组件将imgkey props发送给子组件。当子组件加载该图像时,它可以更改img并通过回调更改其状态来返回父对象。

现在父组件具有其他功能,并且当其他功能更改状态时,子组件(图像)每次都会加载。如何防止在相同的imgkey道具上重新加载?

总体上,当父级发送与之前发送的道具imgkey相同的子级时,子级不应重新加载

1 个答案:

答案 0 :(得分:0)

我相信这取决于您的孩子组成部分,如果孩子需要:

  • 保持渲染或跟进一些逻辑;或
  • 它是可有可无的,我们可以跳过渲染

孩子

该组件将保持渲染状态,有时仅在需要时运行一些逻辑。

class Child extends Component {
  static getDerivedStateFromProps(props, state) {
    if (props.id % 10 === 0) {
      return { shouldRunLogic: true };
    }
    return { shouldRunLogic: false };
  }
  constructor(props, context) {
    super(props, context);
    this.state = { shouldRunLogic: false };
  }
  componentDidMount() {
    // Let's do our stuff once DOM mounted
    this.handleSomeLogic();
  }
  componentDidUpdate(prevProps, prevState) {
    // Do we need to call our logic again?
    if (this.state.shouldRunLogic) {
      this.handleSomeLogic();
    }
  }
  handleSomeLogic() {
    // do some stuff
    this.props.onFinish('Child finished the logic');
  }
  render() {
    // Makes sure we always render for children if any
    return <div>{this.props.id}-{this.props.children}</div>;
  }
}

DispensableChild

此组件仅做一件事,并且在逻辑完成后再也不会重新渲染。

class DispensableChild extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = { isComplete: false };
  }
  componentDidMount() {
    // Let's do our stuff once DOM mounted
    this.handleSomeLogic();
  }
  shouldComponentUpdate(nextProps, nextState) {
    return !this.state.isComplete;
  }
  handleSomeLogic() {
    // do some stuff
    // ...
    // Let's make sure this component never render again
    this.setState({ isComplete: true }, () => this.props.onFinish('DispensableChild finished the logic'));
  }
  render() {
    return this.state.isComplete || <div>Doing some logic</div>;
  }
}

父母

包括两个子组件,但只有“子”组件将继续渲染。

class Parent extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = { childId: 1 };
    this.handleFinish = this.handleFinish.bind(this);
  }
  componentDidMount() {
    // Let's pass the prop every 15 secs
    setInterval(() =>
      this.setState(({ childId }) => ({ childId: childId + 1})), 15000);
  }
  handleFinish(message) {
    console.log(message);
  }
  render() {
    return (
      <div>
        <Child id={this.state.childId} onFinish={this.handleFinish} />
        <DispensableChild id={this.state.childId} onFinish={this.handleFinish} />
      </div>
    );
  }
}