Map/Filter/Reduce é legal. É legal usar underscore/lodash/etc.. e usar uma variedade de funções auxiliares. Mas FP é bem mais que isso. FP é uma mudança de mindset Em praticamente todas as linguagens funcionais, o mindset do desenvolvedor é orientado por funções puras (sem side-effects), ou seja: dada uma entrada, ela irá, via de regra, sempre retornar o mesmo valor. E isso leva ao uso de estruturas de dados imutáveis.
function soma(a, b) { lancaMissilNuclear(); return a + b; } Dados mutáveis em muitos casos dificultam a compreensão do código, principalmente quando não são explícitos para o caller da função. Exemplo de side-effects nao explicito function soma(a, b) { lancaMissilNuclear(); return a + b; } Em tempo de execução, uma série de mutações no estado de um objeto também dificulta a compreensão do data-flow da aplicação.
1, b: 2 } > const immutableObj = Object.freeze(obj); { a: 1, b: 2 } > immutableObj.a = 3 { a: 1, b: 2 } Object.freeze retorna um objetivo imutável. Mas será que ele é útil? Não é explícita a diferença entre um objeto Frozen e Não-Frozen.
1, b: 2 } > const immutableObj = Object.freeze(obj); { a: 1, b: 2 } > changed = Object.assign({}, immutableObj, {a:3}) { a: 3, b: 2 } Usando Object.assign, estamos criando cópias de toda a estrutura do objeto. Usado com muita frequencia, iremos causar uso alto de memória, e uma pressão alta no Garbage Collector. Fora que essa API é horrível
baseando no ótimo trabalho do Chris Okasaki (Purely Functional Data Structures), é possível ter uma performance muito boa utilizando Persistent Data Structures.
é uma lista mutável //o retorno de withMutations é imutável > const list2 = list1.withMutations(function (list) { list.push(4).push(5).push(6); }); > assert(list1.count() === 3); > assert(list2.count() === 6); Aplicando uma mutação para criar um novo objeto imutável tem um overhead, que pode causar uma leve queda de performance caso sejam feitas muitas alterações frequentemente. Se você precisa aplicar uma série de mutações localmente antes de retornar, Immutable lhe dá a capacidade de criar uma cópia temporária mutável (transitório) de uma coleção e aplicar um lote de mutações de uma forma performática usando withMutations. Na verdade, isso é exatamente como o próprio Immutable aplica mutações complexas.
estado da aplicação explícito e imutável, usando funções puras (sem side-effects lembra?) sempre que possível. E todo o estado da aplicação existe em um único Atom: um objeto com valores aninhados contendo todos os dados necessários para a aplicação.
são persistentes, e as versões antigas dos dados são mantidas, é bem fácil desfazer alguma operação. Basta setar o estado global da aplicação para seu valor anterior.
Comparar se dois valores imutáveis são iguais é muito fácil, e isso facilita bastante na hora de ter componentes puros em React. Componentes puros em React são aqueles que, dado os mesmos props e state, não precisam ser re-renderizados. Isso pode dar um grande aumento de desempenho
sim map.get(‘property’) Usar Immutable.Record ajuda, pois ele dá suporte a value.property, e é imutável. List não dá para usar list[0], e sim list.get(0) Libs de terceiros não são compativeis com Immutable values. `toJS()` nessa hora ajuda bastante. As vezes pode ser dificil saber se está trabalhando com um JS object, ou um Immutable object. Comentários ajudam. Usar um type-system (Typescript ou Flow) também podem ajudar bastante.