La specifica ES2023 introduce ora quattro metodi per gli array — toSorted, toReversed, toSpliced e with — che restituiscono nuovi array invece di mutare l'originale. In React e in altre librerie UI che si affidano allo stato immutabile, questi helper permettono agli sviluppatori di sostituire i trucchi con l'operatore spread, che da tempo rappresentano una fonte di bug e boilerplate.

Perché questo cambiamento è importante

React decide se ri-renderizzare un componente confrontando il riferimento dello stato precedente con quello nuovo. Se il riferimento non cambia, React assume che non sia cambiato nulla. Il classico metodo Array.prototype.sort ordina l'array in loco e restituisce lo stesso riferimento, quindi una chiamata come setTasks(prev => prev.sort(fn)) lascia React "cieco" rispetto all'aggiornamento. L'interfaccia utente rimane bloccata su dati obsoleti, un bug che si presenta troppo spesso nei progetti reali.

Gli sviluppatori hanno aggirato il problema clonando prima l'array — tipicamente con l'operatore spread — in modo che il passaggio di ordinamento produca un nuovo riferimento:

setTasks(prev => [...prev].sort((a, b) => b.priority - a.priority));

Quel pattern funziona, ma aggiunge rumore ed è facile dimenticarsene. I nuovi metodi ES2023 offrono un modo diretto e leggibile per produrre un nuovo array mantenendo intatto l'originale.

I quattro metodi non mutanti

  • toSorted(compareFn?) – si comporta come sort ma restituisce una copia ordinata. Nessuna modifica all'array di origine.
  • toReversed() – sostituisce reverse. Restituisce una copia invertita, lasciando intatto l'ordine originale.
  • toSpliced(start, deleteCount, ...items) – rispecchia splice senza effetti collaterali. L'array restituito riflette l'inserimento o la rimozione, mentre l'originale rimane invariato.
  • with(index, value) – sostituisce l'elemento all'indice index con value e restituisce un nuovo array. Sostituisce il comune pattern di map o la sostituzione di elementi tramite l'operatore spread.

Tutti e quattro i metodi fanno parte dello standard ECMAScript e sono disponibili nelle versioni attuali dei principali browser e in Node.js 20.

Come appare il codice ora

Ordinare una lista

// Before
setTasks(prev => [...prev].sort((a, b) => b.priority - a.priority));

// After
setTasks(prev => prev.toSorted((a, b) => b.priority - a.priority));

Aggiornare un singolo elemento

// Before
setItems(prev =>
  prev.map((item, i) => (i === idx ? newItem : item))
);

// After
setItems(prev => prev.with(idx, newItem));

Invertire un array

setLogs(prev => prev.toReversed());

Rimuovere un elemento

setTags(prev => prev.toSpliced(removeIdx, 1));

La nuova sintassi elimina la necessità di operatori spread extra o cicli di mapping, rendendo gli aggiornamenti dello stato più facili da leggere e meno soggetti a errori.

Chi ne beneficia e chi potrebbe esitare

Gli sviluppatori che utilizzano React, Vue, Redux, Zustand o qualsiasi framework che si aspetti strutture dati immutabili ottengono un modello mentale più chiaro: chiama un metodo, ottieni un nuovo array, passalo al setter. La riduzione del boilerplate può anche far risparmiare alcuni millisecondi nei cicli di rendering, poiché il motore evita di creare una copia intermedia prima dell'ordinamento.

I team con browser legacy potrebbero dover includere dei polyfill. I metodi non sono presenti nelle versioni più vecchie di Safari o Internet Explorer, quindi una build di produzione che punta a quelle piattaforme deve includere un fallback. Ciò comporta un piccolo aumento della dimensione del bundle, ma il compromesso spesso vale la pena per il guadagno in leggibilità.

Gli autori di librerie potrebbero dover aggiornare le definizioni dei tipi (ad esempio, TypeScript) per esporre le nuove firme. Finché queste definizioni non arriveranno nei pacchetti ufficiali @types, gli sviluppatori potrebbero riscontrare errori di tipo temporanei.

Cosa monitorare in futuro

  • Metriche di adozione – strumenti come ESLint potrebbero presto aggiungere regole che segnalano le chiamate a array mutabili nei setter dello stato, spingendo gli sviluppatori verso i nuovi metodi.
  • Studi sulle prestazioni – i primi benchmark suggeriscono che i metodi nativi non mutanti siano più veloci di una clonazione tramite operatore spread seguita da un'operazione mutante, ma i dati del mondo reale confermeranno l'impatto.
  • Ulteriori proposte – il comitato ECMAScript continua a esplorare API "immutable-by-default"; tenere d'occhio le prossime fasi potrebbe rivelare altri helper che seguono lo stesso pattern.

In sintesi

L'ultima specifica ECMAScript offre agli sviluppatori UI un modo integrato e conciso per mantenere lo stato immutabile senza le acrobazie dell'operatore spread che hanno causato innumerevoli bug. Sostituendo sort, reverse, splice e le sostituzioni basate sull'indice con toSorted, toReversed, toSpliced e with, permetti al sistema di rilevamento delle modifiche di React di funzionare come previsto e rendi il tuo codice più facile da leggere. Se i browser di destinazione supportano i nuovi metodi — o se sei disposto a usare i polyfill — è il momento di abbandonare i vecchi pattern e lasciare che sia il linguaggio a fare il lavoro pesante.