Home > Back-end >  Why are components not updating their content after a call to setState()?
Why are components not updating their content after a call to setState()?

Time:02-08

I am trying to show user-specific data in a simple page using React. However, even after being able to fetch the user data using axios for HTTP requests and calling setState() to update the state of the root component, the data shown in the page is still not changing.

Here is the code for the main component:

    class UserPage extends React.Component {
    constructor (props) {
        super (props)

        this.state = {userId: null, username: null, clientId: null, jobs: null}
    }

    componentDidMount () {
        getSessionUserData ()
        .then (res => {
            this.setState({userId: res.data.id, username: res.data.username, clientId: res.data.client_id})
        })
    }

    render () {
        console.log ("rendering", this.state)
        return (
            <div id="user-page">
                <PageHeader text={"Welcome, "   this.state.username} id="user-page-header"/>
            </div>
        )
    }
}

As you can see, PageHeader takes data from the main component's state. Here is the code for the PageHeader component:

export class PageHeader extends React.Component {
    constructor (props) {
        super(props)

        this.state = {text: props.text}
    }

    render () {
        console.log ("rendering header with text: ", this.props.text)
        return (
            <h1 id={this.props.id}>{this.state.text}</h1>
        )
    }
}

I added the console.log() inside the UserPage component's render() method in order to check if it was being called after setState() and to make sure the state had been updated, and it turns out it is indeed being called, and the state is indeed being updated. Here is an image of what the console prints out whenever I reload the page:

Image showing page and console output

In the image you can see that the render() method is being called again after setState() and the state has the new user data. Also, I added console logs for the PageHeader component's render() method to check if for some reason it was not being re-rendered, but they are being printed and with the correct text, so I don't quite understand why the data in the page is not changing. Could you please help me figure out why this is happening?

CodePudding user response:

You are passing to

<h1 id={this.props.id}>{this.state.text}</h1>

State which was set in the constructor. Constructor is called once with initial props. Since you set ID to component, it is not recreated (reused). And you print this.props.text but render this.state.text. So you either have to implement 'componentDidUpdate' to react on props changes and there update your state or just simply replace <h1 id={this.props.id}>{this.state.text}</h1> to <h1 id={this.props.id}>{this.props.text}</h1>

CodePudding user response:

If you use this.props.text instead of the this.state.text in the h1 tag then it should work. The state in the PageHeader component is being set on the constructor, which will only happen on the component creation, it will not be re-set on the second render.

export class PageHeader extends React.Component {
    constructor (props) {
        super(props)

        this.state = {text: props.text}
    }

    render () {
        console.log ("rendering header with text: ", this.props.text)
        return (
            <h1 id={this.props.id}>{this.props.text}</h1>
        )
    }
}
  •  Tags:  
  • Related