kansiho
kansiho

Reputation: 532

Get default state value by receiving prop data - React

I'm new to react.js. I'd like to get default value of state following_status by receiving props.user.following_status.

I'm passing user object ( user = { following_status: 'following', id:123 } ) to ReactionButton component. ReactionButton component is looks like this:

class RelationButton extends React.Component {

  constructor(props){
    super(props);
    console.log(props.user.following_status) #  undefined!!!

    this.state = {
      following_status: props.user.following_status
    }
...
    render() {
       if (this.state.following_status == 'following') {
         <UnFollowBtn/>
       } else {
         <FollowBtn/>
       }
    }

RelationButton was called by UserCardHeader component.

const UserCardHeader = (props) => {
  const user = props.user;
  return(
    <header className="user-card--full__header">
      <RelationButton user={user}></RelationButton>
    </header>
  )
}

I don't understand why console.log(props.user.following_status) returns undefined. I googled many websites like those:

those answers suggest

class FirstComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          x: props.initialX
        };
    }
}

but this didn't work for me.

If I add componentWillReceiveProps to the codes above,

  componentWillReceiveProps(props){
    console.log(props.user.following_status)   #=> "following"
    this.setState({following_status: props.user.following_status})
  }

everything works well. However I think it's weird solution and sometimes doesn't work. Why can't I receive object props in constructor(props) {} section?

Upvotes: 1

Views: 1406

Answers (1)

Tomasz Mularczyk
Tomasz Mularczyk

Reputation: 36209

Without the full code, we can't tell what's wrong but it is obvious that following_status comes asynchronously to the component and that's why is not accessible right away in the constructor.

To somehow fix it you can detect if props have changed and reset state accordingly in componentDidUpdate.

class RelationButton extends React.Component {

  constructor(props){
    super(props);
    console.log(props.user.following_status) #  undefined!!!

    this.state = {
      following_status: props.user.following_status
    }
  }

  componentDidUpdate(prevProps) {
    if(prevProps.user.following_status !== this.props.user.following_status) {
      this.setState({ following_status: this.props.user.following_status })
    }
  }

  render() {
     // you forgot about return statements :
     if (this.state.following_status == 'following') {
       return <UnFollowBtn/>
     } else {
       return <FollowBtn/>
     }
  }
}

Upvotes: 1

Related Questions