簡體   English   中英

將 .setState() 之后的狀態傳遞給子組件,但未顯示在子組件的 this.props 中

[英]Passing state after .setState() to child component but not showing up in this.props for child component

為什么我能夠在運行 componentDidMount() 后打印我的 this.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;

在第一個組件初始化中,它將使用其props 但是稍后,如果將其props設置為this.props = newProps ,則此newProps將在componentWillReceiveProps可用。 您可以在這里獲取newProps並執行您想要協助state任何事情。

另外,您可以在這里參考以了解React的生命周期。

setState()並不總是立即更新組件。 它可能會批量更新或將更新推遲到以后。 這使得在調用setState()之后立即讀取this.state可能是一個陷阱。 而是使用componentDidUpdate或setState回調(setState(updater,callback)),確保在應用更新后均能觸發這兩種方法。 如果需要基於先前的狀態來設置狀態,請閱讀以下有關updater參數的信息。

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

React setState是一個異步函數,有時他們批處理您的狀態並將其放入隊列,在這種情況下,可能是這樣的:

嘗試console.log componentWillReceiveProps內部的道具

例如

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

原因是構造函數在初始渲染時僅被調用一次,然后再調用一次,並且您在Child構造函數中記錄了props值,因此,如果您想在Child中看到更新后的值,則它將始終打印初始props值,將控制台放入渲染器中打印更新的值。

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

在已安裝的組件接收新道具之前,將調用componentWillReceiveProps()。

像這樣:

class Main extends React.Component {

  render() {

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

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

您的代碼中的問題在於,在HomePage.js的第一個render調用之后會調用componentDidMount 因此,道具在子代中可用,並且由於子代中的構造函數僅被調用一次,因此不會更新道具。 如果要從子項中的props更新狀態,或者如果要直接使用它,請在子項組件中使用componentWillReceivePropscomponentDidMount ,如果要直接在渲染器中使用它

PS確保在孩子中執行未定義的檢查

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;

您可以通過 componentWillReceiveProps 方法簡單地刷新子組件 (Main.js) 的狀態,如下所示。

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

  componentWillReceiveProps(nextProps) {
    this.setState({ data: this.nextProps.dataParentToChild }); // Refresh data  
    console.log(this.nextProps);  // PRINTS ==> {email: "updated value"}
  }
  
  render() {
    return (
      <div> Test </div>
    );
  }
}

export default Main;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM