Both works in that case, but you don't need to use that. Just setting the state will be okay:

this.setState({active: false})

But let me explain what if you have nested level of states like:

state = {
  foo: {
   a: 1,
   b: 2,
   c: 3
  }
}

And when you need to update the foo's c state only, then you'll need to merge the state like:

this.setState({ foo: {
  ...this.state.foo,
  c: 'updated value'
}})

So, the spread syntax merges object with later object. It's similar to Object.assign.

Answer from Bhojendra Rauniyar on Stack Overflow
🌐
Medium
medium.com › @thejasonfile › using-the-spread-operator-in-react-setstate-c8a14fc51be1
Using the spread operator in React setState | by Jason Arnold | Medium
May 25, 2017 - addNote(newNote) { this.setState({ toDoNotes: [...this.state.toDoNotes, newNote]}) } When the .addNote() function is called and passed a newNote object, the toDoNotes section of the state is updated so that it now includes the previous state as well as the addition of newNote. The spread operator is one of those tools that I tend to forget about because I don’t use it often enough.
Discussions

Using the spread operator in setState hook
Why bother even asking this? Try it out and see what happens. It will be much quicker? 🤷‍♂️ More on reddit.com
🌐 r/reactjs
5
0
October 6, 2019
reactjs - Spread operator in React .setState() in the useState Hook - Stack Overflow
Why is the spread operator used in setName() function how does it work. What this code does is it takes the input from the user and displays it on the screen but before using spread operator the More on stackoverflow.com
🌐 stackoverflow.com
Why use the spread operator when calling 'setState()' in React?
I just start picking up react.js so I went through a lot of tutorials and I've stumbled upon this bit which basically meant to delete an item from the state. this is how the guy introduced to me the More on stackoverflow.com
🌐 stackoverflow.com
reactjs - setState with spread operator - Stack Overflow
I was learning Forms in React and I came across the below code where a single setState method is used for multiple inputs to update the value provided by the user. Can anyone explain what spread operator doing here, what does it hold inside the setState method? More on stackoverflow.com
🌐 stackoverflow.com
🌐
DEV Community
dev.to › gamil91 › react-setstate-59l0
React setState() - DEV Community
September 14, 2021 - Clicking the button the first time will still console.log 0 but clicking it again the second time and the component re-renders, it will log 3. You can also use this if you’re updating an existing array or object in state by using the spread operator like so : state = { arr : [{obj1}, {obj2}, {obj3}] } handleClick = () => { this.setState(prevState => { return {array: [...prevState.arr, {newObj}]} }) }
🌐
Rock Your Code
rockyourcode.com › react-set-state-with-prev-state-and-object-spread-operator
React setState() with prevState and Object Spread Operator | rockyourcode
September 30, 2021 - // Correct this.setState((state, props) => ({ counter: state.counter + props.increment })); Let’s say you have an object in your state and want to use the object spread syntax: // This is the state of your React component this.state = { person: { firstName: "", secondName: "" } }; Now you want to change the state: this.setState(prevState => ({ person: { ...prevState.person, firstName: "Tom", secondName: "Jerry" } })); This also works: this.setState(() => ({ person: { ...this.state.person, firstName: "Tom", secondName: "Jerry" } })); Using functions is now the recommended way to set state in React.
🌐
10xdev
10xdev.blog › react-spread-operator-props-setstate
ES6 Spread Operator in React by Example: Props and setState |
November 6, 2019 - You can spread the props attributes to pass it in JSX using the Spread operator which passes the whole props object.
🌐
javascriptroom
javascriptroom.com › blog › spread-operator-in-react-setstate
Why Use the Spread Operator in React .setState()? (Even When the App Works Without It)
React’s automatic merging only works for top-level state properties. For nested objects, omitting the spread operator will overwrite nested properties, losing data. Example: Nested User Profile Suppose your state has a nested user object: this.state = { user: { name: "Alice", contact: { email: "[email protected]", phone: "555-1234" } }, theme: "light" }; ... // ❌ Bad: Overwrites the entire `contact` object! this.setState({ user: { contact: { email: "[email protected]" } } });
🌐
Stack Overflow
stackoverflow.com › questions › 68826619 › spread-operator-in-react-setstate-in-the-usestate-hook
reactjs - Spread operator in React .setState() in the useState Hook - Stack Overflow
First Name gets erased when last name was entered why did this happen and when using spread operator it provides the previous value and the code works perfect I want to know the logic behind this. Copyimport React from "react"; const Count2 = () => { const [name, setName] = React.useState({ firstName: " ", lastName: " " }); return ( <div> <input type="text" value={name.firstName} onChange={(e) => setName({ ...name, firstName: e.target.value })} /> <input type="text" value={name.lastName} onChange={(e) => setName({ ...name, lastName: e.target.value })} /> <h2>Your first Name is - {name.firstName}</h2> <h2>Your first Name is - {name.lastName}</h2> </div> ); }; export default Count2;
Find elsewhere
Top answer
1 of 4
4

As per the documentation:

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

  • reactjs.org/docs/react-component.html#state

So, in the example from the tutorial you've mentioned, you wouldn't need to make a copy of the array to update your state.

// GOOD
delTodo = id => {
  this.setState({
    todos: this.state.todos.filter(...)
  })
}

Array.filter method creates a new array and does not mutate the original array, therefore it won't directly mutate your state. Same thing applies to methods such as Array.map or Array.concat.

If your state is an array and you're applying methods that are mutable, you should copy your array.

See more to figure out which Array methods are mutable:

  • doesitmutate.xyz

However, if you were to do something like the following:

// BAD
delTodo = id => {
  const todos = this.state.todos
  todos.splice(id, 1)
  this.setState({ todos: todos })
}

Then you'd be mutating your state directly, because Array.splice changes the content of an existing array, rather than returning a new array after deleting the specific item. Therefore, you should copy your array with the spread operator.

// GOOD
delTodo = id => {
  const todos = [...this.state.todos]
  todos.splice(id, 1)
  this.setState({ todos: todos })
}

Similarly with objects, you should apply the same technique.

// BAD
updateFoo = () => {
  const foo = this.state.foo // `foo` is an object {}
  foo.bar = "HelloWorld"
  this.setState({ foo: foo })
}

The above directly mutates your state, so you should make a copy and then update your state.

// GOOD
updateFoo = () => {
  const foo = {...this.state.foo} // `foo` is an object {}
  foo.bar = "HelloWorld"
  this.setState({ foo: foo })
}

Hope this helps.

2 of 4
3

Why use the spread operator at all?

The spread operator ... is often used for creating shallow copies of arrays or objects. This is especially useful when you aim to avoid mutating values, which is encouraged for different reasons. TLDR; Code with immutable values is much easier to reason about. Long answer here.

Why is the spread operator used so commonly in react?

In react, it is strongly recommended to avoid mutation of this.state and instead call this.setState(newState). Mutating state directly will not trigger a re-render, and may lead to poor UX, unexpected behavior, or even bugs. This is because it may cause the internal state to differ from the state that is being rendered.

To avoid manipulating values, it has become common practice to use the spread operator to create derivatives of objects (or arrays), without mutating the original:

// current state
let initialState = {
    user: "Bastian",
    activeTodo: "do nothing",
    todos: ["do nothing"]
}


function addNewTodo(newTodo) {
    // - first spread state, to copy over the current state and avoid mutation
    // - then set the fields you wish to modify
    this.setState({
        ...this.state,
        activeTodo: newTodo,
        todos: [...this.state.todos, newTodo]
    })
}

// updating state like this...
addNewTodo("go for a run")
// results in the initial state to be replaced by this:
let updatedState = {
    user: "Bastian",
    activeTodo: "go for a run",
    todos: ["do nothing", "go for a run"]
}

Why is the spread operator used in the example?

Probably to avoid accidental state mutation. While Array.filter() does not mutate the original array and is safe to use on react state, there are several other methods which do mutate the original array, and should not be used on state. For example: .push(), .pop(),.splice(). By spreading the array before calling an operation on it, you ensure that you are not mutating state. That being said, I believe the author made a typo and instead was going for this:

 delTodo = id => {
    this.setState({
      todos: [...this.state.todos].filter(todo => todo.id !== id)
    });
  };

If you have a need to use one of the mutating functions, you can choose to use them with spread in the following manner, to avoid mutating state and potentially causing bugs in your application:

// here we mutate the copied array, before we set it as the new state
// note that we spread BEFORE using an array method
this.setState({
      todos: [...this.state.todos].push("new todo")
});

// in this case, you can also avoid mutation alltogether:
this.setState({
      todos: [...this.state.todos, "new todo"]
});
🌐
Stack Overflow
stackoverflow.com › questions › 60618020 › setstate-with-spread-operator
reactjs - setState with spread operator - Stack Overflow
setState in React should not mutate state. Instead with help of the spread operator a new object is being created containing the old values and the new [name] property.
🌐
DhiWise
dhiwise.com › post › how-to-simplify-your-react-code-with-the-spread-operator
The Ultimate Guide To Using The React Spread Operator
October 31, 2023 - Mutating State Directly: One common mistake is to use the spread operator to mutate the state directly. In React, you should never mutate the state directly. Instead, you should always use setState (in class components) or the state update function returned by useState (in functional components) to update the state.
🌐
Stack Overflow
stackoverflow.com › questions › 74446657 › how-to-use-spread-operator-in-setstate-react-class-component
How to use spread operator in setstate react class component
Mock: const items = { itemList: { itemOne: [{ id: "01", category: "It-A", isCreated:"true" }], itemDesc:[{ id:"01", type:"A-1", isCreated:"true" }] } ItemID:'123' } Code: class ItemComp extends React.Component{ this.state = { processingItems:[] onAddItemHandle = (processingItem) => { this.setState(prevState => ({ processingItems: [...prevState.processingItems, processingItem] })) } JEST: describe('handleonAddItem', () => { it('should allow to add multiple items based on prevState', () => { const compView = mountWithIntl( <compView itemId={12} /> } const instance = compView.find(compViewCompone
🌐
Medium
medium.com › @truongtronghai › spread-operator-ba867a0e97b4
Spread operator. Some ways to use it in React Js | by Truong Trong Hai | Medium
October 3, 2024 - const [state, setState] = useState({ ... combinedList = [...list1, ...list2]; // [1, 2, 3, 4, 5, 6] The spread operator can also be used to create a shallow copy of an object, which is useful for immutability in React....
Top answer
1 of 3
4

Based upon the name setValues I assume you are referring to functional component state. (useState hook updates don't work quite the same as class-based component's setState lifecycle function)

Using the spread syntax allows for maintaining existing state, i.e. the new update [event.target.name]: event.target.value is merged into current state.

Given state { 'foo': 'bar' }

setValues(values => ({
   ...values, ['bizz']: 'buzz'
}))

New state { 'foo': 'bar', 'bizz': 'buzz' }

Without spreading in the previous state you are simply overwriting it with just an object {[event.target.name]: event.target.value}, so all previous state is lost.

Given state { 'foo': 'bar' }

setValues({
  ['bizz']: 'buzz'
})

New state { 'bizz': 'buzz' }

There are actually a couple things going on here. First is the spread syntax, the other is what is called a functional update. Functional updates allow the update to access the current state and make changes. This is a necessity when the next state depends on the previous state, like incrementing counters, and multiple state updates can be queued up during each render cycle.

setCount(count => count +1)

In the case of a form component where each property is an independent piece of state, then the following syntax is ok since each update to a field overwrites the current value:

setValues({
  ...values,
  [fieldName]: fieldValue
})
2 of 3
0

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

For example, this code may fail to update the counter:

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

We used an arrow function above, but it also works with regular functions:

// Correct
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

Read more here on their official documentation

🌐
IQCode
iqcode.com › code › javascript › spread-operator-react
spread operator react Code Example
October 28, 2021 - spread operator react spread elementt in array react spread operator in javascript and react reactjs rest operator spread operator in react component spread operator reacr how to use the spread operator in states react spread object into set state using spread operator in push array. react react native user spread to set array of objects spread operator and react state spread operator and react this spread operator react spread and rest syntax react native spread operator in react js how to use spread operator in react why we use spread operator in react react spread state react spread array s
Top answer
1 of 1
1

Excess property check only triggered when you try to assign an object literal. For other cases TypeScript only checks if the shape of object matches with the requested type. The reasoning is that it is most likely a developer error when you pass a wrong shaped object inlined. What could be the benefit to allow that? So it is a typo or you want something else.

But if you pass a variable, it only has to check if shape is ok, there can't be really any runtime issue. You can do, for example, the following:

 const [parts, setParts] = useState<parts>({
        general: false,
        source: false,
        target: false,
        wrongKey: "Typescript reports problem"
    } as parts)

That way TypeScript will make sure you pass 'something' which can be shaped as parts. Don't know if it is useful, tho, consider it just as an example:)

I'm not sure if this is really an issue that you are not aware about passing an extraneous property. I would like to stress if you forgot to pass a property to satisfy the shape of the required type, TypeScript will tells you that, and that is what important.

If you really want to deny extra properties, please check this answer: Is it possible to restrict TypeScript object to contain only properties defined by its class?

UPDATE 1: Why excess property check is not triggered, as actually we return with an object literal and I said excess property check run in those case, this is kinda a contradiction, but not, actually.

Consider this example:

type Parts = {
general: boolean;
source: boolean;
target: boolean;
}

type FunctionType = (parts: Parts) => Parts;

function ShowsError(parts: Parts): Parts {
 return {
   ...parts,
   someExtraPropertyWhichTriggerError:'Ooops'
 }
}

const myArrowFunction = (parts: Parts) => ({
  ...parts,
  someExtraPropertyWithoutError:'Why no report?:('
});


const DoesntShowError: FunctionType = myArrowFunction;

So what is happening there? Looks like two identical function, one is arrow, one is normal, why there is no error in case of arrow function? Same arguments, same return type, same object returned.

The key difference is, when we define our arrow function its return statement NOT contextually binded to Parts. TypeScript can't know where it is going to be used. So its generate a shape for its return type, and go on. Then we assign it to DoesntShowError which requires us assign a function with a given type. And the arrowfunction satisfy that requirement. Thats all, I think, hope it helps.