Защо Immer работи добре за неизменност на състоянието на React?

В React използването на състояние Imutable позволява бързо и евтино сравнение на дървото на състоянието преди и след промяна. В резултат на това всеки компонент решава дали да се изобрази повторно или не, преди да извърши каквито и да е скъпи DOM операции.

И се надявам, че вече знаете това;

JavaScript е променлив и ние трябва сами да внедрим неизменността.

Популярните библиотеки за управление на състоянието като Redux също следват същата философия. Когато използваме намаления, той очаква от нас да не мутираме състоянието, за да избегнем странични ефекти в приложението. Въпреки това ръчното внедряване на Immutability може да не е най-добрият вариант за мащабни проекти, където може да стане податливо на грешки.

За щастие има специализирани JavaScript библиотеки като Immer, които налагат Неизменност на дървото на състоянието по дизайн.

Какво представлява Immer и как действа

Immer е малка библиотека, създадена да помогне на разработчиците с неизменно състояние, базирано на механизъм копиране при запис, техника, използвана за прилагане на операция за копиране на модифицируеми ресурси.

В Имер има 3 основни щата.

  1. Текущо състояние: Данни за действителното състояние
  2. Черново състояние: Всички промени ще бъдат приложени към това състояние.
  3. Следващо състояние: Това състояние се създава въз основа на мутациите в черновото състояние.

Immer се представя доста добре от гледна точка на производителността в сравнение с плиткото копиране, използвайки object.assign() или оператор Spread в JavaScript. Ако се интересувате да научите повече за сравненията на ефективността, вижте статията „Immer vs Shallow copy vs Immutable Perf Test“, за да разберете бенчмарковете.

Immer също така намалява количеството код, който трябва да напишете, за да постигнете горните резултати от бенчмарка и това е една от причините Immer да се откроява от останалите.

Тъй като имате основно разбиране за Immer, нека да видим защо Immer е признат за едно от най-добрите решения за неизменност.

Защо Immer работи добре за неизменност на състоянието на React?

Може да получите усещането, че Immer усложнява вашия код, ако работите с прости състояния. Но Immer става много полезен, когато става въпрос за работа с по-сложни данни.

За да разберем по-добре това, нека разгледаме известния пример за редуктор на React:

export default (state = {}, action) => {
    switch (action.type) {
        case GET_ITEMS:
            return {
                ...state,
                ...action.items.reduce((obj, item) => {
                    obj[item.id] = item
                    return obj
                }, {})
            }
        default:
            return state
    }
}

Кодът по-горе показва типичен редуктор на React-Redux, който използва ES6 оператор за разпространение, за да се потопи във вложените нива на обекта на дървото на състоянието, за да актуализира стойностите. Можем лесно да намалим сложността в горния код с помощта на Immer.

Нека вземем пример как можем да използваме Immer, за да намалим сложността на практика.

import produce from "immer"

export default produce((draft, action) => {
    switch (action.type) {
        case GET_ITEMS:
            action.items.forEach(item => {
                draft[item.id] = item
            })
    }
}, {})

В този пример Immer опростява кода, използван за разпространение на състоянието. Можете също да видите, че той мутира обекта чрез използване на цикъл ForEach вместо функция ES6 намаляване.

Нека видим друг пример, където можем да използваме Immer с React.

import produce from "immer";
this.state={
    id: 14,
    email: "stewie@familyguy.com",
    profile: {
      name: "Stewie Griffin",
      bio: "You know, the... the novel you've been working on",
      age:1
    }
}
changeBioAge = () => {
    this.setState(prevState => ({
        profile: {
            ...prevState.profile,
            age: prevState.profile.age + 1
        }
    }))
}

Този код може да бъде преработен чрез мутиране на състоянието, както е показано по-долу

changeBioAge = () => {
    this.setState(
        produce(draft => {
            draft.profile.age += 1
        })
    )
}

Както можете да видите, Immer е намалил драстично броя на кодовите редове и сложността на вашия код.

Съвет: Създайте по-добри библиотеки на компоненти и системи за проектиране

Споделяйте компоненти между екипи и проекти, за да ускорите разработката и да се уверите, че вашите потребители изпитват последователен дизайн във всяка точка на допир.

OSS инструменти като Bit предлагат страхотно изживяване за разработка за изграждане, споделяне и приемане на компоненти в екипи и приложения. Създайте компонентен център безплатно опитайте го →

Можем ли да го използваме с куки?

Друга важна характеристика на Immer е способността му да работи с React Hooks. Immer използва допълнителна библиотека, наречена use-immer, за да постигне тази функционалност. Нека разгледаме един пример, за да разберем по-добре.

const [state, setState] = useState({
    id: 14,
    email: "stewie@familyguy.com",
    profile: {
      name: "Stewie Griffin",
      bio: "You know, the... the novel you've been working on",
      age:1
    }
  });
function changeBio(newBio) {
    setState(current => ({
      ...current,
      profile: {
        ...current.profile,
        bio: newBio
      }
    }));
  }

Можем допълнително да опростим примера с Hooks, като заменим useState с useImmer Hook. И можем също така да актуализираме компонента на React, като променим състоянието на компонента.

import { useImmer } from 'use-immer';
const [state, setState] = useImmer({
    id: 14,
    email: "stewie@familyguy.com",
    profile: {
      name: "Stewie Griffin",
      bio: "You know, the... the novel you've been working on",
      age:1
    }
 });
function changeBio(newBio) {
   setState(draft => {
      draft.profile.bio = newBio;
    });
  }

Също така можем да използваме Immer, за да конвертираме масиви и набори в неизменни обекти. Карти, Наборисъздадени чрез Immer ще хвърлят грешки, когато бъдат мутирани, което позволява на разработчиците да знаят за грешката на мутацията.

Най-важното е, че Immer не е ограничен за React. Можете лесно да използвате Immer и с обикновен JavaScript.

Освен Immutating, Immer помага за поддържането на добре написана, четлива кодова база, като намалява сложността на вашата кодова база.

Последни мисли

Въз основа на моя опит с Immer, вярвам, че това е чудесен вариант за използване с React. Това ще опрости вашия код и ще ви помогне да управлявате неизменността по проект.

Можете да намерите повече информация за Immer, като се обърнете към тяхната документация.

Благодаря ви за четенето !!!

Научете повече