We want to hear from you!Take our 2021 Community Survey!

Auxiliares de Imutabilidade

Nota:

update é um add-on legado. Em vez disso, use immutability-helper.

Importando

import update from 'react-addons-update'; // ES6
var update = require('react-addons-update'); // ES5 com npm

Visão geral

O React permite que você use qualquer estilo de gerenciamento de dados que desejar, incluindo mutação. No entanto, se você puder usar dados imutáveis ​​em partes críticas de desempenho de seu aplicativo, é fácil implementar um método rápido shouldComponentUpdate() para acelerar significativamente seu aplicativo.

Lidar com dados imutáveis ​​em JavaScript é mais difícil do que em linguagens projetadas para isso, como Clojure. No entanto, nós fornecemos um simples auxiliar de imutabilidade, update(), que torna muito mais fácil lidar com esse tipo de dados, sem alterar fundamentalmente a forma como seus dados são representados. Você também pode dar uma olhada no Facebook Immutable-js e na seção de desempenho avançado para obter mais detalhes sobre Immutable-js.

A ideia principal

Se você alterar dados assim:

myData.x.y.z = 7;
// ou...
myData.a.b.push(9);

Você não tem como determinar quais dados foram alterados desde que a cópia anterior foi substituída. Em vez disso, você precisa criar uma nova cópia de myData e alterar apenas as partes que precisam ser alteradas. Então você pode comparar a cópia antiga de myData com a nova em shouldComponentUpdate() usando triplos iguais:

const newData = deepCopy(myData);
newData.x.y.z = 7;
newData.a.b.push(9);

Infelizmente, cópias profundas são custosas e às vezes impossíveis. Você pode aliviar isso copiando apenas os objetos que precisam ser alterados e reutilizando os objetos que não foram alterados. Infelizmente, no JavaScript de hoje, isso pode ser complicado:

const newData = extend(myData, {
  x: extend(myData.x, {
    y: extend(myData.x.y, {z: 7}),
  }),
  a: extend(myData.a, {b: myData.a.b.concat(9)})
});

Embora isso tenha um bom desempenho (já que apenas faz uma cópia superficial de objetos log n e reutiliza o resto), é um grande trabalho escrever. Olhe para toda a repetição! Isso não é apenas irritante, mas também fornece uma grande área de superfície para bugs.

update()

update() fornece “syntactic sugar” simples em torno deste padrão para tornar a escrita deste código mais fácil. Este código se torna:

import update from 'react-addons-update';

const newData = update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});

Embora a sintaxe demore um pouco para se acostumar (pelo fato de ser inspirada na linguagem de consulta do MongoDB), não há redundância, é estaticamente analisável e não tem muito mais digitação do que a versão mutativa.

As chaves prefixadas com $ são chamadas de comandos (command). A estrutura de dados que eles estão “mutando” é chamada de destino (target).

Comandos disponíveis

  • {$push: array} push() todos os itens em array no destino.
  • {$unshift: array} unshift() todos os itens em array no destino.
  • {$splice: array of arrays} para cada item em arrays chama splice() no destino com os parâmetros fornecidos pelo item.
  • {$set: any} substitui o destino inteiramente.
  • {$merge: object} mescla as chaves de object com o destino.
  • {$apply: function} passa o valor atual para a função e o atualiza com o novo valor retornado.

Exemplos

Push simples

const initialArray = [1, 2, 3];
const newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]

initialArray ainda é [1, 2, 3].

Coleções aninhadas

const collection = [1, 2, {a: [12, 17, 15]}];
const newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
// => [1, 2, {a: [12, 13, 14, 15]}]

Isso acessa o índice 2 da collection, chave a, e faz uma junção de um item começando no índice 1 (para remover 17) enquanto insere 13 e 14.

Atualizando um valor com base no valor atual

const obj = {a: 5, b: 3};
const newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});
// => {a: 5, b: 6}
// Isso é equivalente, mas fica detalhado para coleções profundamente aninhadas:
const newObj2 = update(obj, {b: {$set: obj.b * 2}});

Mesclagem (Superficial)

const obj = {a: 5, b: 3};
const newObj = update(obj, {$merge: {b: 6, c: 7}}); // => {a: 5, b: 6, c: 7}
Esta página é útil?Edite esta página