简体   繁体   中英

Wait for react props received from parent to update inside a childs function

I have a function that Is executed in componentDidMount() , because it does an API call, and I need the info received for the render.

componentDidMount() {
    this.setState({
        email: this.props.email
    });
    this.getPermissionsList();
    this.getPermissionsValue(); //this one
}

Now, this function has the following issue

 getPermissionsValue(){
        console.log('/user/'+this.props.userId+'/permission') //At the moment of the execution, this.props.userId is empty
        API.get('/user'+this.props.userId+'/permission')
            .then(response => {
            console.log(response)
            this.setState({
                permissionValue : response.data
            }, () => {
                console.log(this.state.permissionValue)
            });

        })
    }

But in my render, I can see the this.props.userId value.

    render(){
       return  <p>{this.props.userId}</p>  
} 

How can I wait for that prop before rendering?

EDIT : This is how the prop is being sent to the child from the parent

In the parent component I have a child component in the render

<EditUserModal ...a lot of props.... userId={this.state.rowId} email={this.state.selectedMail} handleChangePass={this.handleChangePass} ....more props..../>

That rowId is assigned this way in the parent component:

In my render I have this

<Table
                     className="table"
                     filterable={['Email']}
                     itemsPerPage={8}
                     currentPage={0}
                     sortable={true}
                >
                    {users.map((row) => {
                        return (

                            <Tr className={row.className}>
                                <Td column="Email">{row.email}</Td>
                                <Td column="Edit" ><FontAwesomeIcon className="editIcon" onClick={()=> this.showModal(row.id, row.email)} icon={faEdit} /></Td> 
                            </Tr>

                        )
                    })}
                </Table>

where the onclick calls

showModal(rowId, rowEmail) {
    this.setState({
        showModal: true,
        rowId: rowId,
        selectedMail: rowEmail
    }, () => {
        // console.log("clicked show modal")
        // console.log(this.state.showModal)
    });

}

And thats where the rowId state value is set

In your scenario, I think there are a lot of chances that componentDidMount in your child component fires before this.props.userId get value. (I think your user array comes from an API call too). You can look into discussion in this thread to see why it could happen.

My suggestion is, instead of putting the API call in the componentDidMount() , put it into componentDidUpdate() , if you do the comparison, you don't need to worry about calling the API multiple times. It's a typical usage recommended in the official doc

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    yourAPI(this.props.userID);
  }
}

Also here is an answer I wrote before trying to compare where to deploy the API calls.

You can use the second argument of setState:

componentDidMount() {
  this.setState({
    email: this.props.email
  }, () => {
    this.getPermissionsList();
    this.getPermissionsValue(); //this one
  });
}

This ensures that the state gets set first, -then- calls the other two methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM