简体   繁体   中英

Deep merge of complex state in React

When I have the following initial state declared:

  getInitialState: function() {
    return {
      isValid: false,
      metaData: {
        age: 12,
        content_type: 'short_url'
      }
    };
  },

and I update state with setState like this:

...
let newMetaData = {  age: 20 };
...
this.setState({
        isValid: true,
        metaData: newMetaData
      });
...

Resulting this.state.metadata object has only age defined. But as far as I'm aware, this.setState() merges it argument to existing state. Why it's not working here, isn't this supposed to be recurrent merging?

Is there a way to merge new object properties to state object property in React/ES6?

setState performs a shallow merge. If metaData is is flat:

this.setState({
  metaData: Object.assign({}, this.state.metaData, newMetaData),
});

or if using spread :

this.setState({
  metaData: { ...this.state.metaData, ...newMetaData },
});

Another way to approach this, if you only need to update one property, would be like this:

this.setState({
  metaData: {
    ...this.state.metaData,
    age: 20
  }
})

setState 也可以接受一个函数,它接收一个状态参数,你可以使用 lodash merge 进行深度合并。

  setState(state => merge(state, yourPartialObjectToBeDeepMerged));

a tricky solution is here

const [complexObject, setComplexObject] = useState({a:{b:{c:1}}})
setComplexObject((s)=>{
  s.a.b.c = 2
  return {...s}
})

How does it work?

An object is a reference. If you sabc = 2 , this will update the state, but the component doesn't rerender, so the dom will not change.

Then we need a way to rerender the component. If you setComplexObject(s=>s) , it will not trigger rerender, because albeit the interior of the ComplexObject do change, the reference still point at the same object.

So we need ES6 spread operator to reconstruct a object by doing this {...s}

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