- Obsah#
- Proč bych měl používat knihovnu zaměřenou na immutable, jako je Immutable.JS?#
- Další informace#
- Proč bych si měl vybrat Immutable.JS jako neměnnou knihovnu?#
- Zaručená neměnnost#
- Bohaté API#
- Výkon#
- Další informace#
- Obtížná spolupráce s#
- Jakmile jednou použijete Immutable.JS, rozšíří se ve vaší kódové základně#
- Žádné destrukturní nebo rozprostřené operátory#
- Nevhodné pro malé hodnoty, které se často mění#
- Obtížně laditelný#
- Porušuje odkazy na objekty, což způsobuje nízký výkon#
- Další informace#
- Stojí používání Immutable.JS za námahu? #
- Další informace#
- Jaké jsou některé názorové osvědčené postupy pro použití Immutable.JS s Reduxem?#
- Nikdy nemíchejte běžné objekty JavaScriptu s Immutable.JS#
- Další informace#
- Vytvořte celý stavový strom Reduxu jako Immutable.JS#
- Další informace#
- Použít Immutable.JS všude kromě hloupých komponent#
- Další informace#
- Omezte používání toJS()#
- Další informace#
- Vaše selektory by měly vracet objekty Immutable.JS#
- Používejte objekty Immutable.JS ve svých inteligentních komponentách#
- Další informace#
- Nikdy nepoužívejte toJS() v mapStateToProps#
- Další informace#
- Další informace#
- K převodu rekvizit Immutable.JS vaší inteligentní komponenty na rekvizity JavaScriptu vaší hloupé komponenty použijte komponentu vyššího řádu#
- Další informace#
- Pomocí rozšíření Immutable Object Formatter pro Chrome usnadníte ladění#
Obsah#
- Proč bych měl používat knihovnu zaměřenou na immutable, jako je Immutable.JS?
- Proč bych měl zvolit Immutable.JS jako immutable knihovnu?
- Jaké jsou problémy s použitím Immutable.JS?
- Stojí Immutable.JS za námahu?
- Jaké jsou osvědčené postupy pro použití Immutable.JS s Reduxem?
Proč bych měl používat knihovnu zaměřenou na immutable, jako je Immutable.JS?#
Knihovny zaměřené na immutable, jako je Immutable.JS, byly navrženy tak, aby překonaly problémy s neměnností, které jsou vlastní jazyku JavaScript, a poskytly všechny výhody neměnnosti s výkonem, který vaše aplikace vyžaduje.
Zda se rozhodnete použít takovou knihovnu, nebo zůstanete u obyčejného JavaScriptu, záleží na tom, nakolik vám vyhovuje přidání další závislosti do vaší aplikace nebo nakolik jste si jisti, že se dokážete vyhnout úskalím, která jsou vlastní přístupu JavaScriptu k neměnnosti.
Ať už se rozhodnete pro kteroukoli možnost, ujistěte se, že jste obeznámeni s koncepty neměnnosti, vedlejších efektů a mutací. Zejména se ujistěte, že dobře rozumíte tomu, co JavaScript dělá při aktualizaci a kopírování hodnot, abyste se ochránili před náhodnými mutacemi, které sníží výkon vaší aplikace nebo ji úplně rozbijí.
Další informace#
Dokumentace
- Recepty: neměnnost, vedlejší efekty a mutace
Články
- Úvod do neměnnosti.js a koncepty funkcionálního programování
- Pro a proti používání neměnnosti s React.js
Proč bych si měl vybrat Immutable.JS jako neměnnou knihovnu?#
Immutable.JS byl navržen tak, aby poskytoval neměnnost výkonným způsobem ve snaze překonat omezení neměnnosti s JavaScriptem. Mezi její hlavní výhody patří:
Zaručená neměnnost#
Data zapouzdřená v objektu Immutable.JS nejsou nikdy mutována. Vždy je vrácena nová kopie. To kontrastuje s JavaScriptem, ve kterém některé operace data nemutují (např. některé metody pole, včetně map, filter, concat, forEach atd.), ale některé ano (pop, push, splice pole atd.).
Bohaté API#
Immutable.JS poskytuje bohatou sadu neměnných objektů pro zapouzdření dat (např.Mapy, seznamy, množiny, záznamy atd.) a rozsáhlou sadu metod pro manipulaci s nimi, včetně metod pro třídění, filtrování a seskupování dat, jejich obrácení, zploštění a vytváření podmnožin.
Výkon#
Immutable.JS dělá spoustu práce v zákulisí, aby optimalizoval výkon. To je klíč k jeho výkonu, protože používání neměnných datových struktur může zahrnovat spoustu nákladného kopírování. Zejména neměnná manipulace s velkými a složitými datovými sadami, jako je například vnořený stavový strom Reduxu, může generovat mnoho mezilehlých kopií objektů, které spotřebovávají paměť a zpomalují výkon, protože sběrač odpadu prohlížeče bojuje o úklid.
Immutable.JS se tomu vyhýbá chytrým sdílením datových struktur pod povrchem, čímž minimalizuje potřebu kopírování dat. Umožňuje také provádět složité řetězce operací bez vytváření zbytečných (a nákladných) klonovaných mezidat, která budou rychle vyhozena.
To samozřejmě nikdy neuvidíte – data, která předáte objektu Immutable.JS, nejsou nikdy mutována. Spíše jsou to mezidata generovaná v rámci Immutable.JS ze zřetězené posloupnosti volání metod, která mohou být volně mutována. Získáte tedy všechny výhody neměnných datových struktur bez (nebo jen s velmi malým) potenciálním zásahem do výkonu.
Další informace#
Články
- Immutable.js, persistentní datové struktury a sdílení struktur
- PDF: Jaké jsou problémy s používáním Immutable.JS? #
Ačkoli je Immutable.JS mocný, je třeba ho používat opatrně, protože s sebou nese vlastní problémy. Všimněte si však, že všechny tyto problémy lze poměrně snadno překonat pečlivým kódováním.
Obtížná spolupráce s#
JavaScript neposkytuje neměnné datové struktury. Aby tedy Immutable.JS poskytoval své záruky neměnnosti, musí být vaše data zapouzdřena v objektu Immutable.JS (například
Map
neboList
atd.). Jakmile jsou tato data takto obsažena, je pro ně obtížné následně spolupracovat s jinými, běžnými objekty JavaScriptu.Například již nebude možné odkazovat na vlastnosti objektu prostřednictvím standardní tečkové nebo závorkové notace JavaScriptu. Místo toho se na ně musíte odkazovat prostřednictvím metod
get()
nebogetIn()
souboru Immutable.JS, které používají nepohodlnou syntaxi, jež k vlastnostem přistupuje prostřednictvím pole řetězců, z nichž každý představuje klíč vlastnosti.Například místo
myObj.prop1.prop2.prop3
byste použilimyImmutableMap.getIn()
.To způsobuje nepohodlnou spolupráci nejen s vaším vlastním kódem, ale také s jinými knihovnami, jako je lodash nebo ramda, které očekávají prosté objekty JavaScriptu.
Všimněte si, že Immutable.JS objekty mají metodu
toJS()
, která vrací data jako prostou datovou strukturu JavaScriptu, ale tato metoda je extrémně pomalá a její rozsáhlé používání bude negovat výkonnostní výhody, které Immutable.JS poskytujeJakmile jednou použijete Immutable.JS, rozšíří se ve vaší kódové základně#
Jakmile zapouzdříte data pomocí Immutable.JS, musíte pro přístup k nim použít přístupové prvky vlastností Immutable.JS
get()
nebogetIn()
To má za následek rozšíření Immutable.JS po celé vaší kódové základně, včetně potenciálně vašich komponent, kde byste možná raději takové externí závislosti neměli. Celá vaše kódová základna musí vědět, co je a co není objekt Immutable.JS. To také ztěžuje odstranění Immutable.JS z vaší aplikace v budoucnu, pokud byste to někdy potřebovali.
Tomu problému se lze vyhnout oddělením logiky aplikace od datových struktur, jak je popsáno v části o osvědčených postupech níže.
Žádné destrukturní nebo rozprostřené operátory#
Protože musíte přistupovat k datům prostřednictvím Immutable.JS vlastní metody
get()
agetIn()
, nemůžete již používat destrukturovací operátor JavaScriptu (ani navrhovaný operátor Object spread), čímž se váš kód stane rozvláčnějším.Nevhodné pro malé hodnoty, které se často mění#
Immutable.JS funguje nejlépe pro kolekce dat, a čím větší, tím lépe. Může být pomalý, když se vaše data skládají z mnoha malých, jednoduchých objektů JavaScript, z nichž každý obsahuje několik klíčů primitivních hodnot.
Všimněte si však, že to neplatí pro stavový strom Reduxu, který je (obvykle) reprezentován jako velká kolekce dat.
Obtížně laditelný#
Immutable.JS objekty, jako jsou
Map
,List
apod, mohou být obtížně laditelné, protože kontrola takového objektu odhalí celou vnořenou hierarchii vlastností specifických pro Immutable.JS, které vás nezajímají, zatímco vaše skutečná data, která vás zajímají, jsou zapouzdřena několik vrstev hluboko.Pro vyřešení tohoto problému použijte rozšíření prohlížeče, například Immutable.js Object Formatter, které v nástroji Chrome Dev Tools zobrazí vaše data a při kontrole dat skryje vlastnosti Immutable.JS.
Porušuje odkazy na objekty, což způsobuje nízký výkon#
Jednou z klíčových výhod neměnnosti je, že umožňuje mělkou kontrolu rovnosti, což výrazně zlepšuje výkon.
Pokud dvě různé proměnné odkazují na stejný neměnný objekt, pak stačí jednoduchá kontrola rovnosti obou proměnných, aby se zjistilo, že jsou si rovny a že objekt, na který obě odkazují, se nezměnil. Kontrola rovnosti nikdy nemusí kontrolovat hodnoty žádné z vlastností objektu, protože ten je samozřejmě neměnný.
Mělká kontrola však nebude fungovat, pokud jsou vaše data zapouzdřená v objektu Immutable.JS sama o sobě objektem. Je to proto, že metoda Immutable.JS
toJS()
, která vrací data obsažená v objektu Immutable.JS jako hodnotu JavaScriptu, vytvoří při každém svém volání nový objekt, a tak přeruší odkaz se zapouzdřenými daty.Příklad dvojí volání metody
toJS()
a přiřazení výsledku dvěma různým proměnným způsobí selhání kontroly rovnosti těchto dvou proměnných, i když se samotné hodnoty objektů nezměnily.Tento problém nastane zejména v případě, že metodu
toJS()
použijete ve funkcimapStateToProps
zabalené komponenty, protože React-Redux mělce porovnává každou hodnotu ve vráceném objektu props. Například hodnota, na kterou odkazujetodos
prop vrácený zmapStateToProps
níže, bude vždy jiný objekt, a proto neprojde mělkou kontrolou rovnosti.// AVOID .toJS() v mapStateToPropsfunction mapStateToProps(state) {return {todos: state.get(‚todos‘).toJS() // Vždy nový objekt}}Kopírovat
Pokud mělká kontrola selže, React-Redux způsobí opětovné vykreslení komponenty. Použití
toJS()
vmapStateToProps
tímto způsobem tedy vždy způsobí opětovné vykreslení komponenty, i když se hodnota nikdy nezmění, což má velký dopad na výkon.Tomu lze zabránit použitím
toJS()
v komponentě vyššího řádu, jak je popsáno v části Nejlepší postupy níže.Další informace#
Články
- Immutable.js, perzistentní datové struktury a sdílení struktur
- Immutable Data Structures and JavaScript
- React.js pure render performance anti-pattern
- Building Efficient UI with React and Redux
Chrome Extension
- Immutable Object Formatter
Stojí používání Immutable.JS za námahu? #
Často ano. Je třeba zvážit různé kompromisy a názory, ale existuje mnoho dobrých důvodů, proč Immutable.JS používat. Nepodceňujte obtížnost snahy vystopovat vlastnost stromu stavů, která byla neúmyslně zmutována.
Komponenty se jednak znovu vykreslují, i když by se vykreslovat neměly, jednak se odmítají vykreslovat, i když by se vykreslovat měly, a vystopovat chybu způsobující problém s vykreslováním je obtížné, protože nesprávně vykreslovaná komponenta nemusí být nutně ta, jejíž vlastnosti byly omylem zmutovány.
Tento problém je způsoben převážně vracením zmutovaného objektu stavu z reduktoru Redux. S Immutable.JS tento problém jednoduše neexistuje, čímž z vaší aplikace odstraníte celou třídu chyb.
To je spolu s jeho výkonem a bohatým API pro manipulaci s daty důvod, proč se Immutable.JS vyplatí.
Další informace#
Dokumentace
- Řešení problémů: Při odeslání akce se nic nestane
Jaké jsou některé názorové osvědčené postupy pro použití Immutable.JS s Reduxem?#
Immutable.JS může vaší aplikaci přinést výrazné zlepšení spolehlivosti a výkonu, ale musí se správně používat. Pokud se rozhodnete Immutable.JS používat (a nezapomeňte, že to není nutné a že existují i jiné immutable knihovny, které můžete použít), dodržujte tyto názorově shodné osvědčené postupy a budete z něj moci vytěžit maximum, aniž byste narazili na některý z problémů, které může potenciálně způsobit.
Nikdy nemíchejte běžné objekty JavaScriptu s Immutable.JS#
Nikdy nedovolte, aby běžný objekt JavaScriptu obsahoval vlastnosti Immutable.JS. Stejně tak nikdy nedovolte, aby objekt Immutable.JS obsahoval prostý objekt JavaScriptu.
Další informace#
Články
- Immutable Data Structures and JavaScript
Vytvořte celý stavový strom Reduxu jako Immutable.JS#
Pro aplikaci Redux by celý váš stavový strom měl být objektem Immutable.JS a vůbec nepoužívejte žádné obyčejné objekty JavaScriptu.
-
Vytvořte strom pomocí funkce Immutable.JS
fromJS()
. -
Použijte Immutable.JS-aware verzi funkce
combineReducers
, například tu v redux-immutable, protože Redux sám očekává, že stavový strom bude prostým objektem JavaScriptu. -
Při přidávání objektů JavaScriptu do mapy nebo seznamu Immutable.JS pomocí Immutable.JS metodami
update
,merge
neboset
, zajistěte, aby byl přidávaný objekt nejprve převeden na objekt Immutable pomocífromJS()
.
Příklad
// vyhněte seconst newObj = { key: value }const newState = state.setIn(, newObj)// newObj byl přidán jako prostý JavaScriptový objekt, NE jako Immutable.JS Map// doporučenoconst newObj = { key: value }const newState = state.setIn(, fromJS(newObj))// newObj je nyní Immutable.JS MapKopírovat
Další informace#
Články
- Immutable Data Structures and JavaScript
Knihovny
- redux-immutable
Použít Immutable.JS všude kromě hloupých komponent#
Používání Immutable.JS všude udržuje výkonnost vašeho kódu. Používejte jej ve svých chytrých komponentách, selektoru, sázích nebo thuncích, tvůrcích akcí a zejména v reduktorech.
Nepoužívejte však Immutable.JS ve svých hloupých komponentách.
Další informace#
Články
- Immutable Data Structures and JavaScript
- Chytré a hloupé komponenty v Reactu
Omezte používání toJS()#
toJS()
je drahá funkce a popírá účel použití Immutable.JS. Vyhněte se jejímu používání.Další informace#
Diskuse
- Lee Byron na Twitteru: „Perf tip for #immutablejs…“
Vaše selektory by měly vracet objekty Immutable.JS#
Vždy. Tento postup má několik výhod:
- Předchází zbytečnému opakování volání
.toJS()
v selektoru (protože.toJS()
vždy vrátí nový objekt).- Je možné memoizovat selektory, ve kterých voláte
.toJS()
, ale je to zbytečné, když stačí vracet objekty Immutable.js bez memoizace.
- Je možné memoizovat selektory, ve kterých voláte
- Vytváří konzistentní rozhraní pro selektory; nebudete muset sledovat, zda bude vrácen objekt Immutable.js nebo obyčejný objekt JavaScriptu.
Používejte objekty Immutable.JS ve svých inteligentních komponentách#
Chytré komponenty, které přistupují k úložišti prostřednictvím funkce
connect
React Redux, musí používat hodnoty Immutable.JS vrácené vašimi selektory. Ujistěte se, že se vyhnete možným problémům, které může způsobit zbytečné překreslování komponent. V případě potřeby si selektory zapamatujte pomocí knihovny, například reselect.Další informace#
Dokumentace
- Recepty: Výpočet odvozených dat
- FAQ: Dokumentace k výběru: Neměnná data
- Dokumentace k výběru:
Články
- Redux Patterns and Anti-Patterns
Knihovny
- Reselect: Reselect: knihovna selektorů pro Redux
Nikdy nepoužívejte toJS() v mapStateToProps#
Konverze objektu Immutable.JS na objekt JavaScript pomocí
toJS()
vrátí pokaždé nový objekt. Pokud to provedete vmapStateToProps
, způsobíte, že se komponenta bude domnívat, že se objekt změnil při každé změně stromu stavů, a vyvoláte tak zbytečné opětovné vykreslení.Další informace#
Dokumentace
- FAQ: JS v hloupých komponentách#
Vaše hloupé komponenty by měly být čisté, to znamená, že by měly produkovat stejný výstup při stejném vstupu a neměly by mít žádné vnější závislosti. Pokud takové komponentě předáte objekt Immutable.JS jako rekvizitu, učiníte ji závislou na Immutable.JS při získávání hodnoty rekvizity a jiné manipulaci s ní.
Taková závislost činí komponentu nečistou, ztěžuje testování komponenty a zbytečně ztěžuje její opětovné použití a refaktorizaci.
Další informace#
Články
- Immutable Data Structures and JavaScript
- Chytré a hloupé komponenty v Reactu
- Tipy pro lepší architekturu Redux: Poučení pro podnikové měřítko
K převodu rekvizit Immutable.JS vaší inteligentní komponenty na rekvizity JavaScriptu vaší hloupé komponenty použijte komponentu vyššího řádu#
Něco musí mapovat rekvizity Immutable.JS ve vaší inteligentní komponentě na rekvizity čistého JavaScriptu použité ve vaší hloupé komponentě. Tím něčím je komponenta vyššího řádu (HOC), která jednoduše převezme rekvizity Immutable.JS z vaší Chytré komponenty a převede je pomocí
toJS()
na čisté rekvizity JavaScriptu, které pak předá vaší Hloupé komponentě.Příklad takové HOC následuje. Podobný HOC je pro vaše pohodlí k dispozici jako balíček NPM: with-immutable-props-to-js.
import React from ‚react‘import { Iterable } from ‚immutable‘export const toJS = WrappedComponent => wrappedComponentProps => {const KEY = 0const VALUE = 1const propsJS = Object.entries(wrappedComponentProps).reduce((newProps, wrappedComponentProp) => {newProps] = Iterable.isIterable(wrappedComponentProp)? wrappedComponentProp.toJS(): wrappedComponentPropreturn newProps},{})return <WrappedComponent {…propsJS} />}Copy
A takto byste to použili ve své inteligentní komponentě:
import { connect } from ‚react-redux‘import { toJS } from ‚./to-js‘import DumbComponent from ‚./dumb.component‘const mapStateToProps = state => {return {// obj je Immutable objekt v Smart Component, ale toJS ho převede na čistý// JavaScript objekt, a tak ho předá DumbComponent jako čistý JavaScript// objekt. Protože se však zde v mapStateToProps stále jedná o objekt Immutable.JS,// nevzniká problém s chybným opětovným vykreslením.obj: getImmutableObjectFromStateTree(state)}}export default connect(mapStateToProps)(toJS(DumbComponent))Kopírovat
Převedením objektů Immutable.JS na obyčejné hodnoty JavaScriptu v rámci HOC dosáhneme přenositelnosti Dumb Component, ale bez výkonnostních zásahů použití
toJS()
v Smart Component.Poznámka: pokud vaše aplikace vyžaduje vysoký výkon, možná se budete muset
toJS()
úplně vyhnout, a tak budete muset v dumb komponentách používat Immutable.JS. Pro většinu aplikací to však nebude tento případ a výhody ponechání Immutable.JS mimo vaše hloupé komponenty (udržovatelnost, přenositelnost a snazší testování) budou daleko převažovat nad jakýmkoli domnělým zlepšením výkonu při jeho ponechání v komponentě.Použití
toJS
v komponentě vyššího řádu by navíc nemělo způsobit velké, pokud vůbec nějaké, zhoršení výkonu, protože komponenta bude volána pouze při změně rekvizit připojené komponenty. Stejně jako v případě jakéhokoli problému s výkonem proveďte nejprve kontrolu výkonu, než se rozhodnete, co optimalizovat.Další informace#
Dokumentace
- React: Komponenty vyššího řádu
Články
- React Komponenty vyššího řádu do hloubky
Diskuze
- Reddit: acemarke a cpsubrian komentují Dan Abramov: Redux není architektura ani návrhový vzor, je to jen knihovna
Gists
- cpsubrian: React decorators for redux/react-router/immutable ‚smart‘ components
Pomocí rozšíření Immutable Object Formatter pro Chrome usnadníte ladění#
Nainstalujte si Immutable Object Formatter , a kontrolujte data Immutable.JS, aniž byste viděli šum vlastních vlastností objektů Immutable.JS.
.