在重新渲染组件时“剩余”执行代码会怎样?

时间:2019-04-06 12:35:11

标签: javascript reactjs

使用React.js,假设我有一个父组件,该组件的状态列表为:

myList: [1, 2, 3]

我在myList上执行一个.map(),并为列表中的每个项目渲染一个新组件。因此,我的父应用程序现在具有子组件。

假设我在此子组件中运行了一个方法myMethod,在该方法中间的某个地方,我更新了父组件的myList状态变量。

这将触发子组件(包括当前组件)的重新渲染(正确吗?),该子组件正在执行myMethod,但尚未完成该方法的所有行。

主要问题:

myMethod方法内的其余任何代码行之后,会导致该方法的组件重新呈现,那将会发生什么?

(它们仍然会被执行,还是执行会中止?比这更细微的差别?)

1 个答案:

答案 0 :(得分:1)

setState是异步的,因此它不会立即更新您的父组件状态。因此,方法myMethod中的其余代码不会被中止。所有剩余的代码都将被执行,并且仅在该父组件状态被更新后才执行,这将触发重新渲染。而且,如果您愿意,也可以在相同的myMethod方法内更新子组件状态(在axios对后端的请求得到解决之后)。

例如:

import React, { Component } from "react";
import ReactDOM from "react-dom";

const getRandomInt = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

class Parent extends Component {
  state = {
    list: [1, 2, 3]
  };

  parentHandler = value => {
    this.setState({ list: [...this.state.list, value] }, () =>
      console.log("parent component state updated")
    );
  };

  render() {
    return (
      <div>
        {this.state.list.map(item => (
          <Child key={item} item={item} parentHandler={this.parentHandler} />
        ))}
      </div>
    );
  }
}

class Child extends Component {
  state = {
    id: 24
  };

  fakePromsise = () => {
    const newId = getRandomInt(24, 60);
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(newId), 5000);
    });
  };

  childHandler = listItem => {
    let newItem = listItem + getRandomInt(10, 1000);
    // handling parent state
    this.props.parentHandler(newItem);
    // handling fake promise
    // and when the promise resolves
    // update the component state
    this.fakePromsise().then(data =>
      this.setState(
        {
          id: data
        },
        () => console.log("child component state updated")
      )
    );
    // after the loop completes
    // parent state is updated
    for (let i = 0; i < 5000; i++) {
      console.log("i", i);
    }
  };

  render() {
    return (
      <div>
        <h1 onClick={() => this.childHandler(this.props.item)}>
          {this.props.item} click me!!!
        </h1>
        <p>Id: {this.state.id}</p>
      </div>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'));
  

您可以使用示例并查看控制台结果。只需单击h1标签。之后,添加新的Child组件,并更改单击的Child组件id