Tornando o estado do Redux imutável
Nas suas viagens pelo ecossistema do Redux já deve ter ouvido o termo Imutabilidade, mas o que significa isso e por que aplicar esse conceito no gerenciamento de estado?
Basicamente, dizer que algo é imutável é dizer que não pode sofrer alterações, sejam elas feitas pelo usuário ou derivadas de ações terceiras criadas pela aplicação. Mas pera aí, o estado do Redux precisa mudar, certo? Sim, e não.
O estado não é constante, seu valor muda diversas vezes durante a execução da aplicação, mas isso não quer dizer que ele é alterado. Seguindo o conceito de imutabilidade, o estado nunca é modificado e sim um novo estado é retornando sobrescrevendo o estado atual da aplicação.
Performance
Pense que ao modificar um objeto, a linguagem precisa percorrer todo objeto, buscando pelas propriedades alteradas e adicionando o novo valor à elas. A partir do momento que você segue o conceito de arquitetura Flux do Redux e mantenha um único objeto como estado global da sua aplicação, pense que cada alteração pode ocasionar essa busca por informações ser lenta e custosa para sua aplicação.
Em objetos imutáveis, quando um novo valor é retornado, ele sobrescreve o objeto inicial tornando todo processo mais rápido.
Imutabilidade nativa
O Javascript por padrão possui uma forma de tornar um objeto imutável utilizando o método Object.freeze
da seguinte forma:
let obj = {
name: "RocketZeat",
site: "www.rocketseat.com.br"
};
obj.name = "RocketSeat"; // Funciona
let freezedObj = Object.freeze(obj);
freezedObj.name = "RocketSeeeeat"; // Não funciona
Dessa forma, o objeto se torna imutável e não é possível adicionar, alterar ou remover qualquer propriedade ou característica do objeto. No exemplo acima, o código não retorna nenhum erro, mas caso a notação 'use strict'
for adicionada ao escopo do Javascript, um erro TypeError
é disparado.
O grande problema de tornar um objeto imutável utilizando apenas o freeze
do Javascript é sua performance que em alguns navegadores, como no Safari, é extremamente baixa.
Utilizando a biblioteca seamless-immutable
Uma das formas de unir as vantagens de ter um estado imutável com performance e praticidade na hora de modificar o estado no Redux é utilizando a biblioteca seamless-immutable. Com a lib, remover a mutabilidade de um objeto fica fácil:
import Immutable from 'seamless-immutable';
let obj = Immutable({
name: "RocketSeat"
});
obj.name = "Rocketseeeat"; // Não funciona e dispara ImmutableError
E com a utilização do Immutable você pode utilizar o método merge
para realizar o processo de copiar, alterar e retornar um novo objeto modificado com as novas informações:
let obj = Immutable({
name: "RocketSeat"
});
obj.merge({ name: "Rocketseeeeat" }); // Funciona
Lembrando que o Immutable pode ser utilizado para qualquer tipo de estrutura de dados como inteiros, strings, arrays ou objetos e ele utiliza as funções nativas, como o freeze
, unidas às técnicas próprias para tornar os objetos imutáveis.
Integrando ao Redux
Para integrar o seamless-immutable ao Redux basta utilizá-lo na hora de definir o estado inicial dos seus reducers, como por exemplo:
import Immutable from 'seamless-immutable';
const initialState = Immutable({
data: [],
loading: false
});
const reducer = (state = initialState, action) {
switch (action.type)...
}
Dessa forma, quando você tentar alterar o estado da sua aplicação no reducer sem utilizar o merge
, um erro será disparado e a ação será impedida.
Conclusão
Imutabilidade traz performance e organização ao seu projeto e integrá-la ao Redux torna todo processo ainda mais performático e prazeroso ao desenvolvedor já que o estado fica protegido à alterações inesperadas.
Ah, se gostou do post aproveita pra deixar aquele comentário sobre o que achou.