Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
81
rated 0 times [  82] [ 1]  / answers: 1 / hits: 68547  / 8 Years ago, thu, october 6, 2016, 12:00:00

This question might fall a little on the side of a best practice question, but please bear with me.



Here is a portion of my state:



this.state = {
typeElements: {
headers: [
{
name: h1,
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}, {
name: h2,
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}, {
name: h3,
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}...


What I need to do is REPLACE the object at a given index on the headers array.



I don't know how to do that with the setState method as in this.setState(headers[1] = {obj}) - but that's obviously invalid. My current method is creating a new array and clobbering the old one like this:



_updateStyle(props) {
let newState = Object.assign({}, this.state)
newState.typeElements.headers[props.index] = props
this.setState(newState)
};


For my small hacky project I guess it's OK but I feel like this is super heavy handed and would quickly lead to performance issues at any kind of scale.


More From » arrays

 Answers
7

Updated: since this answer still gets upvotes, be aware that the previous answer below is outdated with modern JavaScript and React. The update addon is now legacy and immutability-helper can be used instead.



The React docs also mention why immutability is important so avoid mutating state. For immutable updates you can use Object.assign() or spread syntax which needs to be done for every level of nesting, like in this example the nested headers object and its array elements. In this particular example we can use the array index as key so it's possible to also use the spread operator to make a shallow clone of the array and assign a new object as value at given index in the cloned array.



_updateStyle (props) {
const { typeElements } = this.state;
const updatedHeaders = [...typeElements.headers];
updatedHeaders[props.index] = props;
this.setState({
...this.state,
typeElements: {
...typeElements,
headers: updatedHeaders
}
));
}


Another solution which doesn't require the spread syntax and is needed if we are not using the array index to find the object we want to replace, is using array.map to create a new array and returning the new object instead of the old one at given index.



  const updatedHeaders = typeElements.headers.map((obj, index) => {
return index === props.index ? props : obj;
});


Similar examples in the Redux docs also explain immutable update patterns.




React has some immutability helpers for this, which is explained in
the docs: https://facebook.github.io/react/docs/update.html



In your case you could use the $splice command to remove one item and
add the new one at given index, for example:



_updateStyle (props) {
this.setState(update(this.state.typeElements,
{ $splice: [[props.index, 1, props]] }
));
}


[#60485] Tuesday, October 4, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
deiong

Total Points: 15
Total Questions: 103
Total Answers: 99

Location: Sudan
Member since Thu, May 7, 2020
4 Years ago
;