In JavaScript gli oggetti si passano per riferimento: assegnarli non li copia. Modificarne uno "condiviso" causa bug subdoli, specie in React dove lo stato va trattato come immutabile.

const stato = { user: { nome: "Ale" }, tag: ["a", "b"] };

// copia SUPERFICIALE: il primo livello è nuovo, l'interno è condiviso
const copia = { ...stato };
copia.user.nome = "Bob";
stato.user.nome; // "Bob" <- ops, mutato anche l'originale!

// copia PROFONDA: tutto duplicato davvero
const clone = structuredClone(stato);
clone.user.nome = "Bob";
stato.user.nome; // "Ale" <- l'originale è salvo

Lo spread ({ ...obj }) e Object.assign copiano solo il primo livello: gli oggetti annidati restano condivisi. Per una copia profonda affidabile c'è structuredClone, ora nativo, che duplica anche strutture annidate, array, Map e Set.

La regola: se aggiorni uno stato annidato in modo immutabile, ricorda che lo spread è superficiale. Per casi semplici copi livello per livello ({ ...stato, user: { ...stato.user, nome } }); per casi profondi, structuredClone. Conoscere la differenza ti risparmia ore di caccia al bug.