将.setState()之后的状态传递给子组件,但不会显示在子组件的this.props中

时间:2017-08-15 18:54:04

标签: javascript reactjs

为什么我在运行componentDidMount()之后能够打印my.state.email但是当我将状态传递给子组件时,我无法在子组件的this.props.email中访问它

class HomePage extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      isAuthorized: false,
      name: "",
      email: "",
    };
  }

  loadGoogleApi() {
    ...
    this.makeApiCall()
    ...
  }

  makeApiCall() {
    gapi.client.people.people.get({
      'resourceName': 'people/me',
      'personFields': 'names,emailAddresses',
    }).then(resp => {
      this.setState({
        name: resp.result.names[0].givenName,
        email: resp.result.emailAddresses[0].value
      });
    });
  }

  componentDidMount() {
    this.loadGoogleApi();
  }

  render() {
    return(
      <div>
        { !this.state.isAuthorized ? (
          <button onClick={ this.handleAuthClick } id="authorize-button">Login/Signup</button>
        ) : (
          <div>
            <p>{ "Hello, " + this.state.name + "!" }</p>
            <p>{ "Hello, " + this.state.email + "!" }</p>
            <Main email={ this.state.email }/>
          </div>
        ) }
      </div>
    );
  }
}

Main.js组件

class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    console.log(this.props);  // PRINTS ==> {email: ""}
  }

  render() {
    return (
      <div> Test </div>
    );
  }
}

export default Main;

4 个答案:

答案 0 :(得分:2)

在第一个组件初始化中,它将采用其props。但是稍后如果您将props设置为this.props = newProps,则此newProps将在componentWillReceiveProps中提供。你可以在这里抓住newProps并做任何你想做的事情,比如分配给state

此外,您可以参考here查看React生命周期。

答案 1 :(得分:1)

  

setState()并不总是立即更新组件。有可能   批量或推迟更新,直到稍后。这使得阅读this.state   在调用setState()之后发生了潜在的陷阱。相反,使用   componentDidUpdate或setState回调(setState(更新程序,   回调)),其中任何一个都保证在更新后触发   已经应用。如果需要根据以前的状态设置状态   state,请阅读下面的updater参数。

字体:https://facebook.github.io/react/docs/react-component.html

React setState是一个异步函数,有时它们批量你的状态并将它放在队列中,在这种情况下可能发生这种情况:

尝试在componentWillReceiveProps

内的console.log中添加道具

e.g。

componentWillReceiveProps(nextProps) {
   console.log(nextProps);
}

答案 2 :(得分:1)

原因是 constructor 在初始渲染后只调用一次,而不是在那之后,您在Child构造函数中记录props值,因此它将始终打印初始道具值如果你想在Child中看到更新的值将控制台放在渲染中,它将打印更新的值。

您还可以使用componentWillReceiveProps生命周期方法检查udpated道具值。

  

在安装的组件之前调用componentWillReceiveProps()   收到新的道具。

像这样:

class Main extends React.Component {

  render() {

    //here
    console.log(this.props);

    return (
      <div> Test </div>
    );
  }
}

答案 3 :(得分:1)

代码中的问题是componentDidMountHomePage.js中的第一次渲染调用之后被调用。因此,孩子可以使用道具,因为孩子中的构造函数只被调用一次,所以道具不会更新。如果要从子项中的props更新状态,或者如果您想直接使用它,则需要在子组件中使用componentWillReceivePropscomponentDidMount,在渲染中使用它

P.S。确保在孩子中执行未定义的检查

class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentWillReceiveProps(nextProps) {
      console.log(nextProps);
  }
  render() {
    console.log(this.props.email);
    return (
      <div> Test </div>
    );
  }
}

export default Main;