Home > Software design >  How to update React component?
How to update React component?

Time:10-14

I have a child object (element of list) which is rendered inside(?) the parent one. The component has the following properties (from JSON):

contract
{
  id,
  name,
} 

But I need to add another one additional property which is filled in after an HTTP request with an external function to the API (for example, uuid) using one of the existing properties of an object. My current React code looks the following way (only child component is provided):

class Contract extends Component {
  constructor(props){
    super(props);
    this.state = {data: this.props.contract};
    getUuidByName(this.state.data.name).then(val => {
      this.state.data.uuid = val;
    });
  }

  componentDidUpdate(){ }

  render() {
    return <tr>
      <td>{this.state.data.id}</td>
      <td>{this.state.data.name}</td>
      <td>{this.state.data.uuid}</td>
    </tr>
  }
}

Everything rendered good except an additional property: uuid. Of course I do something wrong or don't do some important thing, but I have no idea what to do.

CodePudding user response:

Do not modify state directly.

Because you're directly modifying the state, React isn't triggering a re-render.

Try the following in your constructor instead:

constructor(props){
  super(props);
  this.state = {data: this.props.contract};
  getUuidByName(this.state.data.name).then(val => {
    this.setState({
      data: {
        ...this.state.data,
        uuid:  val
      }
    });
  });
}

CodePudding user response:

You are mutating state in the constructor. Never mutate state directly. If you are needing to set/initialize some state after it's been constructed, or mounted, then you should use the componentDidMount lifecycle method. Ensure you enqueue the state update via the this.setState method.

class Contract extends Component {
  constructor(props){
    super(props);
    this.state = {
      data: props.contract,
    };
  }

  componentDidMount() {
    getUuidByName(this.state.data.name).then(val => {
      this.setState(prevState => ({
        data: {
          ...prevState.data,
          uuid: val,
        },
      }));
    });
  }

  componentDidUpdate(){ }

  render() {
    return (
      <tr>
        <td>{this.state.data.id}</td>
        <td>{this.state.data.name}</td>
        <td>{this.state.data.uuid}</td>
      </tr>
    );
  }
}
  • Related