0
votes

I have a parent component where I am updating a nested property on an object in the state of the component. This is the object in the state:

this.state = {
  classObject: {
    description: {...}, // class description
    mergedClasses: [{
      partialClass: {...}, 
      description: {...}
    }]
  }
}

In the method below I am updating the array mergedClasses inside the classObject object:

onUpdatingClasses() {
  this.setState(prevState => {
    const classes = prevState.selectedClasses
      .map(selectedClass => {
        const classObject = prevState.class.mergedClasses.find(classObject => selectedClass.id === classObject.id);
        return classObject
          ? {...classObject}
          : {partialClass: selectedClass});

    return {
      classObject: {
        ...prevState.classObject,
        mergedClasses: classes,
      }
    };
  });
}

Then down the component chain, I have a child component that has tabs, and renders one of this classes from the mergedClasses array. As a default I am setting the first element from the array to render. I am doing this by setting the value of the tab to the index of the first element from that array like this:

state = {
  value: this.props.classObject.mergedClasses[0].partialClass.id,
}; 

This works fine as long as I don't update the first element of the array. Then the component crushes, because the value doesn't get updated with the new first element id. I have tried with checking the props in componentDidUpdate method, but I saw in devtools that it never gets called.

componentDidUpdate(prevProps) {
  if(prevProps.classObject.mergedClasses[0].partialClass.id !== this.props.classObject.mergedClasses[0].partialClass.id) {
    this.setState({value: 
    this.props.classObject.mergedClasses[0].partialClass.id);
  }
}

What am I doing wrong and how can I make a component to update the state with the new props?

1
You're naming a const as class. const class = 'invalid identifier' - Dupocas
sorry, that was just my mistake here, when I was translating variables, in the code it is different - Leff
Where do you exactly update the first element of the array? - Alireza
Why are you returning twice from map? - Dupocas
@Dupocas I am not returning twice from the map, I am returning once in map, and once in setState - Leff

1 Answers

0
votes

You can set the default state in componentDidMount.

For example

componentDidMount() {
  const {
    classObject: { mergedClasses: [{ partialClass: { id } = {} }] = [{}] } = {},
  } = this.props;
  // now you have no undefined values
  this.setState({ value: id });
}

you could also use defaultValues if you are using classes, as in

  state: { ... }
...
  defaultValues: { ... // describe default values here if not set }