首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >componentDidMount中的ReactJS生命周期setState

componentDidMount中的ReactJS生命周期setState
EN

Stack Overflow用户
提问于 2020-07-23 04:37:40
回答 5查看 82关注 0票数 0

我有两个组件来演示我的问题:

父级:

代码语言:javascript
复制
import React from "react";
import ReactDOM from "react-dom";
import { Grid, Row } from "react-flexbox-grid";
import Hello from "./Hello";

class App extends React.Component {
  state = {
    name: "Michal"
  };

  componentDidMount = () => {
    this.setState({ name: "Tina" });
  };

  componentDidUpdate(prevState) {
    console.log("App componentDidUpdate", prevState, this.state);
  }

  handleUpdate = value => {
    console.log("App handleUpdate");
    this.setState({ name: value });
  };

  render() {
    return (
      <Grid>
        <Row>
          <Hello name={this.state.name} update={this.handleUpdate} />
        </Row>
      </Grid>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

孩子:

代码语言:javascript
复制
import * as React from "react";

class Hello extends React.PureComponent {
  componentDidMount() {
    // setTimeout(() => {
    this.props.update("Matus");
    // }, 0);
  }

  componentDidUpdate(prevProps) {
    console.log("Hello componentDidUpdate", prevProps, this.props);
  }

  render() {
    return <h1>Hello {this.props.name}!</h1>;
  }
}

export default Hello;

在子组件中,我希望通过props函数设置父状态中的值。但是props函数被忽略,如果从setTimeout调用setState函数,它就会起作用。

你能给我解释一下为什么它在setTimeout中工作,为什么我应该避免这种构造吗?那么正确的方法是什么呢?

Hello组件代表“选择”,在componentDidMount中它将获取选项并设置默认值。

谢谢。

EN

回答 5

Stack Overflow用户

发布于 2020-07-23 05:10:50

组件在React中自下而上进行初始化。因此,在您的示例中,Hello触发componentDidMount,尝试通过this.props.update在应用程序中设置状态,然后App在调用自己的componentDidMount时瞬间覆盖它。您在子组件中设置的名称永远不会到达该状态。

我不确定这是什么目的,希望只是为了学习的目的,因为组件不应该在挂载时立即设置自己的状态。如果您需要在初始化App中的状态之前执行一些逻辑,您可以使用constructor并在那里执行。

无论如何,解决方案是删除App中的初始状态设置器。

票数 3
EN

Stack Overflow用户

发布于 2020-07-23 05:09:53

它不会被忽略,它确实会触发。你只是没有用你的日志来观察它。查看:

https://codesandbox.io/s/kind-jackson-b2r2b?file=/src/App.js

在控制台中,您将在控制台窗口中看到以下执行顺序:

代码语言:javascript
复制
Hello componentDidMount props = Object {name: "Michal", update: function ()}
App handleUpdate value =  Matus 
App componentDidMount props = Object {}
Hello componentDidUpdate props = Object {name: "Tina", update: function ()}
App componentDidUpdate state = Object {}
Object {name: "Tina"}

因此,您将看到子componentDidMount在父组件完成之前启动并完成挂载,并在组件从子组件向上完成挂载时启动其componentDidMount

所以你永远不会观察到Matus的状态,因为它会在Tina完成挂载时触发一个新的状态更改。

票数 1
EN

Stack Overflow用户

发布于 2020-07-23 05:18:24

由于React生命周期的原因,来自Hello组件的setState函数被忽略。基本上,App componentDidMount函数会在Hello组件呈现之前覆盖它的状态更改。这就是setTimeout提供帮助的原因,它将您的状态更改移动到新的呈现循环。

我不知道您为什么要加载数据并将其从子组件传递到父组件,但React中的良好实践是从上到下传递数据。因此,更好的解决方案是使用Select组件来呈现来自父对象的数据,并对用户事件做出反应。

代码语言:javascript
复制
<Select options={options} selected={option} handle={handleSelect} />
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63042824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档