immutability

Valida contra a mutação de props, estado e outros valores que são imutáveis.

Detalhes da Regra

As props e o estado de um componente são instantâneos imutáveis. Nunca os modifique diretamente. Em vez disso, passe novas props adiante e use a função de atualização do useState.

Violações Comuns

Inválido

// ❌ Mutação de push em array
function Component() {
const [items, setItems] = useState([1, 2, 3]);

const addItem = () => {
items.push(4); // Mutando!
setItems(items); // Mesma referência, sem re-renderização
};
}

// ❌ Atribuição de propriedade de objeto
function Component() {
const [user, setUser] = useState({name: 'Alice'});

const updateName = () => {
user.name = 'Bob'; // Mutando!
setUser(user); // Mesma referência
};
}

// ❌ Ordenação sem espalhamento (spread)
function Component() {
const [items, setItems] = useState([3, 1, 2]);

const sortItems = () => {
setItems(items.sort()); // sort muta!
};
}

Válido

// ✅ Cria novo array
function Component() {
const [items, setItems] = useState([1, 2, 3]);

const addItem = () => {
setItems([...items, 4]); // Novo array
};
}

// ✅ Cria novo objeto
function Component() {
const [user, setUser] = useState({name: 'Alice'});

const updateName = () => {
setUser({...user, name: 'Bob'}); // Novo objeto
};
}

Solução de Problemas

Preciso adicionar itens a um array

Mutar arrays com métodos como push() não aciona re-renderizações:

// ❌ Errado: Mutando o array
function TodoList() {
const [todos, setTodos] = useState([]);

const addTodo = (id, text) => {
todos.push({id, text});
setTodos(todos); // Mesma referência de array!
};

return (
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}

Crie um novo array em vez disso:

// ✅ Melhor: Cria um novo array
function TodoList() {
const [todos, setTodos] = useState([]);

const addTodo = (id, text) => {
setTodos([...todos, {id, text}]);
// Ou: setTodos(todos => [...todos, {id: Date.now(), text}])
};

return (
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}

Preciso atualizar objetos aninhados

Mutar propriedades aninhadas não aciona re-renderizações:

// ❌ Errado: Mutando objeto aninhado
function UserProfile() {
const [user, setUser] = useState({
name: 'Alice',
settings: {
theme: 'light',
notifications: true
}
});

const toggleTheme = () => {
user.settings.theme = 'dark'; // Mutação!
setUser(user); // Mesma referência de objeto
};
}

Use o espalhamento (spread) em cada nível que precisa ser atualizado:

// ✅ Melhor: Cria novos objetos em cada nível
function UserProfile() {
const [user, setUser] = useState({
name: 'Alice',
settings: {
theme: 'light',
notifications: true
}
});

const toggleTheme = () => {
setUser({
...user,
settings: {
...user.settings,
theme: 'dark'
}
});
};
}