ProgramGuru

Updating Objects in State

Updating Objects in State

A student record contains a name and several marks. Correcting one mark should preserve the other information while giving React a new record to render. Changing a property on the existing object is not the right update contract.

Treat objects stored in state as read-only. To change one property, create a new object containing the unchanged properties and the replacement. Then pass that new object to the setter or return it from a functional updater.

  1. Explain

    Create a new student record when correcting a mark.

  2. Trace

    Copy the changed nested marks object as well as its parent.

  3. Apply

    Explain why direct mutation does not reliably request a new screen.

Object Updates: follow the relationship

  1. Original record

    The current snapshot contains the existing student and marks objects.

  2. Create changed copies

    Copy the student and marks objects, then replace the corrected field.

  3. Request the new record

    The setter stores the new value while the old snapshot stays intact.

Read this relationship alongside the complete code. This diagram explains the flow; it does not execute React.

Build the mental model

Object spread copies properties into a new object. Put the changed property after the spread so it overrides the old value. Spread is shallow: nested objects are still shared unless you explicitly copy every level along the changed path.

Preserve record meaning

Replacing a student object with only {maths: 45} loses its name and every other field. Spreading the previous record first states that these fields should remain. A functional updater is particularly helpful if several requests may depend on the latest pending version of the same record.

For an object with many nested paths, outline the changed path before writing spreads. Copy each container along that path and keep untouched branches shared. This is structural sharing: it preserves snapshots without unnecessarily duplicating every unrelated record in the application.

Read the complete React example

The example changes maths from 40 to 45 and keeps name unchanged. The practice stores maths and science inside a marks object, so it copies both the student record and the nested marks object before replacing science.

React · JavaScript with JSX

import React, { useState } from 'react';
export default function App() {
  const [student, setStudent] = useState({ name: 'Asha', maths: 40 });
  return <main><h1>{student.name}</h1><p>Maths: {student.maths}</p><button onClick={() => setStudent(previous => ({ ...previous, maths: 45 }))}>Correct maths</button></main>;
}

Expected screen and behavior

Initial screen: Asha Maths: 40 Correct maths
After selecting Correct maths: the screen includes Maths: 45.

Connect the source to the screen

React · main example

import React, { useState } from 'react';
export default function App() {
  const [student, setStudent] = useState({ name: 'Asha', maths: 40 });
  return <main><h1>{student.name}</h1><p>Maths: {student.maths}</p><button onClick={() => setStudent(previous => ({ ...previous, maths: 45 }))}>Correct maths</button></main>;
}

React can compare the old and new state values by identity. Creating a new record provides a new state value and preserves the earlier snapshot. Mutating the old record breaks the assumption that previous renders retain their own unmodified data.

Avoid the common mistakes

A shallow top-level copy followed by next.marks.science = 38 still mutates a shared nested marks object. Copy the nested object too. Very deeply nested state is harder to update correctly; a flatter structure or reducer may make the domain easier to manage.

Practice before reading the solution

React · starting example

import React, { useState } from 'react';
export default function App() {
  const [student, setStudent] = useState({ name: 'Asha', maths: 40 });
  return <main><h1>{student.name}</h1><p>Maths: {student.maths}</p><button onClick={() => setStudent(previous => ({ ...previous, maths: 45 }))}>Correct maths</button></main>;
}

Correct a nested science mark while preserving the student name and maths mark.

Predict the initial visible text and explain which values determine it. Then inspect the worked solution below. Change one relevant input in your local project and check whether the screen follows your prediction. A working screen should be checked for the intended meaning, not merely the absence of an error.

Worked practice solution

The solution’s two spreads follow the path from the outer record to marks. Only science changes. Use the visible name and maths value as checks that the update retained required data rather than replacing the record with an incomplete object.

React · JavaScript with JSX

import React, { useState } from 'react';
export default function App() {
  const [student, setStudent] = useState({ name: 'Asha', marks: { maths: 40, science: 35 } });
  function correct() {
    setStudent(previous => ({ ...previous, marks: { ...previous.marks, science: 38 } }));
  }
  return <main><h1>{student.name}</h1><p>Maths: {student.marks.maths}</p><p>Science: {student.marks.science}</p><button onClick={correct}>Correct science</button></main>;
}

Expected screen and behavior

Initial screen: Asha Maths: 40 Science: 35 Correct science
After selecting Correct science: the screen includes Science: 38.

Check your reasoning

Choose the explanation that matches React and JavaScript behavior. Review the reasoning for each alternative before moving on.

Why copy both student and student.marks for a nested correction?
Choose one answer. You can try again.

Answer and explanation

A top-level spread still shares the old nested object

Correct. Copying each changed level preserves the earlier nested snapshot.

Use the idea in the next lesson

Treat objects stored in state as read-only. To change one property, create a new object containing the unchanged properties and the replacement. Then pass that new object to the setter or return it from a functional updater.

Continue with Updating Arrays in State. Revisit Queueing State Updates when the relationship between inputs and the resulting screen needs another look.

Read the primary reference: React documentation on Updating Objects in State.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Updating Arrays in State →