πŸš€ Mastering Shallow vs Deep Copy in JavaScript & React – From Scratch to Advanced

krishankrishan
4 min read

✍️ Introduction

If you've ever wondered why updating an object in React causes unexpected changes elsewhere in your app β€” you’ve likely fallen into the shallow copy trap.

In JavaScript, the way objects and arrays are copied can lead to side effects, bugs, and confusing behavior β€” especially in React apps where immutability is key.

This blog will take you from zero to advanced in understanding and using shallow and deep copies, with real-world examples, React use cases, and a drag-and-drop state update challenge!


βœ… Step 1: What is Shallow Copy?

A shallow copy duplicates the top-level properties of an object or array. If there are nested objects or arrays, only their references are copied β€” not their values.

πŸ§ͺ Example:

const original = {
  name: "John",
  address: { city: "London" },
};

const shallowCopy = { ...original };
shallowCopy.address.city = "Paris";

console.log(original.address.city); // πŸ‘‰ "Paris"

❗ Gotcha

Modifying shallowCopy.address.city also changes original.address.city β€” because the address object is shared by reference.


βœ… Step 2: What is Deep Copy?

A deep copy creates a full copy of an object, including all nested objects/arrays. Changes to the copy won’t affect the original.

πŸ”§ Methods to Create Deep Copy:

  1. structuredClone() (Modern browsers)

  2. JSON.parse(JSON.stringify(...)) (Simple but limited)

  3. Libraries like lodash.cloneDeep()

πŸ’‘ Example:

const original = {
  name: "John",
  address: { city: "London" },
};

// βœ… Deep copy
const deepCopy = structuredClone(original);
deepCopy.address.city = "Paris";

console.log(original.address.city); // πŸ‘‰ "London"

βš›οΈ Real-World React Example: Todo State Update

Let’s say you're managing nested project todos in React.

🧠 Why You Need Copying:

React state should not be mutated directly. If you do, React may not detect the change and re-render properly.

βœ… Working Example

const [projects, setProjects] = useState([
  {
    name: "Work",
    todos: [
      { id: 1, task: "Email boss", done: false },
      { id: 2, task: "Finish report", done: true },
    ],
  },
]);

const toggleTask = (projectId, todoId) => {
  const updatedProjects = projects.map((proj, idx) =>
    idx === projectId
      ? {
          ...proj,
          todos: proj.todos.map((todo) =>
            todo.id === todoId ? { ...todo, done: !todo.done } : todo
          ),
        }
      : proj
  );

  setProjects(updatedProjects);
};

βœ… Here, we’re making a shallow copy at each level (projects, proj, and todo) to avoid mutating the original state.


🧩 Step 3: Drag & Drop Challenge with Nested Deep Updates

Imagine a drag-and-drop interface where you move tasks across projects. You must update deep nested arrays safely!

πŸ§ͺ Sample State Structure

const [projects, setProjects] = useState([
  {
    name: "Work",
    todos: [
      { id: 1, task: "Design UI" },
      { id: 2, task: "Fix bugs" },
    ],
  },
  {
    name: "Home",
    todos: [
      { id: 3, task: "Cook dinner" },
    ],
  },
]);

βœ… Challenge: Move task with ID 2 from "Work" to "Home"

const moveTask = (fromIndex, toIndex, taskId) => {
  const clonedProjects = structuredClone(projects);

  const fromTodos = clonedProjects[fromIndex].todos;
  const toTodos = clonedProjects[toIndex].todos;

  const taskToMove = fromTodos.find(todo => todo.id === taskId);
  clonedProjects[fromIndex].todos = fromTodos.filter(todo => todo.id !== taskId);
  toTodos.push(taskToMove);

  setProjects(clonedProjects);
};

βœ… Here, we use structuredClone() for a deep copy to safely update without side effects.


🎯 Step 4: Key Takeaways

πŸ” ConceptShallow CopyDeep Copy
Top-Level Propsβœ… Copiedβœ… Copied
Nested Objects❌ Shared (Reference)βœ… Copied (New References)
React Usage⚠️ Can lead to bugsβœ… Safest for immutability
Methods...spread, Object.assign()structuredClone(), cloneDeep()

πŸŽ“ Interview Questions to Practice

  1. ❓ What is the difference between shallow and deep copy in JavaScript?

  2. ❓ How do you ensure immutability while updating deeply nested React state?

  3. ❓ How would you implement a deep copy in older browsers?

  4. ❓ What issues can arise if you directly mutate a nested object in React?


πŸ’‘ Conclusion

Mastering deep vs. shallow copying will take your JavaScript and React skills to the next level. It’s essential for state management, working with APIs, and building predictable, maintainable apps.

πŸ” Practice with real-world nested objects
βš›οΈ Always treat state as immutable in React
🧠 Know when to use shallow or deep copy!


πŸ”— You can try this on CodeSandbox or StackBlitz to see how it works!

If this helped, give it a like or comment. Happy coding! πŸš€

10
Subscribe to my newsletter

Read articles from krishan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

krishan
krishan

πŸ‘‹ Hey, I'm a Frontend Developer passionate about building clean, user-friendly interfaces. πŸš€ Learning and sharing everything from React, JavaScript, HTML/CSS to advanced topics like Data Structures, Algorithms & System Design. πŸ’» Documenting my journey from fundamentals to becoming a top-tier developer β€” one blog at a time. πŸ“š Join me as I break down complex topics into easy, practical lessons β€” with GitHub repos, code snippets, and real-world examples. πŸ” Consistent growth, community learning, and aiming high!