Реацт схоулдЦомпонентУпдате демистификован

Да ли сте се током развоја у Реацту икад запитали када и зашто се покреће метода рендер () компоненте? Или када користити мање очигледне методе животног циклуса схоулдЦомпонентУпдате ()?

Ако је одговор да, ваша апликација можда има проблема са перформансама. Прочитајте и моћи ћете лако да их поправите.

Све се своди на то како Реацт ради испод хаубе. Реацт-ово велико обећање је да брзо избија елементе на страници.

Да би то урадио, Реацт у меморији чува две верзије ДОМ-а:

  • тренутно приказана верзија ДОМ-а
  • следећа верзија ДОМ-а која ће бити приказана

Поређује та два и ажурира приказани ДОМ само са деловима који су промењени. Овај процес се назива помирење стабала. Корен стабла процењеног за помирење је компонента која се променила.

Сјајно. Без обзира да ли сте то планирали или не, ваша веб апликација прати контејнер / презентационе компоненте до неке мере подељене. Погледајте овде и овде за дефиниције. То значи да је сваки сложени приказ у вашој апликацији направљен од компоненте контејнера која садржи логику и има пуно компонената само за приказ као деца.

Ово је врло добар образац. Ако погледате изблиза, то значи да ће свака интеракција корисника у приказу утицати на сам контејнер и покренути приказивање њега и свих његових подређених. Рецимо да имате листу елемената са фенси приказом текста, слике и дугметом попут жуте звезде „Додај у фаворите“. Минимални модел за елемент листе могао би бити:

product = { imageUrl: '...', title: '...', isFavourite: false }

Листа фаворита може доћи из другог извора података. Без обзира на то, ваша компонентна организација вероватно изгледа отприлике овако:

Руковалац се позива на клик корисника и спрема страну информационог сервера (или остаје у продавници или било шта друго) и покреће промену у тхис.пропс.елементс.

Резултат једног клика покреће приказивање контејнера и свих редова на листи само да би се ажурирао један оквир за потврду.

Овде треба да се појави ЦомпонентУпдате (). Можете рећи Реацт-у да не приказује редове који не морају да користе овај метод.

class ListItem extends Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.isFavourite != this.props.isFavourite; } ... }

Ево конкретног случаја: на пројекту апликације на тржишту имали смо поглед на управљање производима за продавце. Листа је имала образац „учитај више док се корисник помера надоле“ и акције у оквиру ставке „прикажи / сакриј“ за подешавање видљивости сваког производа. Све је било у реду када су продавци управљали са <100 производа на својој контролној табли. Тада је дати продавац почео да улази и рекламира више од 300 производа ...

Било је заостајање од ~ 600мс пре него што се УИ ажурирао након што је корисник кликнуо на икону „омогући / онемогући“. Крајњи корисник је дефинитивно видео заостајање. Користећи Цхроме профилер, видели смо да је Реацт-у требало око 2 мс да се направи један ред. Пута 300 ... имали смо до 600мс. Додали смо провере схоулдЦомпонентУпдате () за одговарајуће услове. Време приказивања након што је клик корисника прешао мање од 10 мс ...

Саставио сам мали пројекат који омогућава репродукцију овог случаја овде. Покрените га и прочитајте коментаре кода да бисте видели чаролију.

Упозорење за кориснике Редук-а

Горе описани проблем може се догодити чешће ако користите Редук и поново изаберете (или сличне библиотеке акционих цеви „засноване на продавници“).

Помоћу Редук-а и поновног одабира радње гурате у продавницу и прикључујете слушаоце да чувају промене, зване селектори. Селектори су глобално доступни у апликацији, а у великој апликацији је многим компонентама прилично лако мапирати исте селекторе. Промене у продавници могу покренути промене реквизита и на тај начин рендере који су потпуно небитни за неке компоненте.

Ево збуњујућег савета: не користите схоулдЦомпонентУпдате () да бисте спречили приказивање у таквим случајевима. Логика изнутра схоулдЦомпонентУпдате треба да гледа само оно што је релевантно за компоненту. Никада не би требало да предвиђа контекст у коме се компонента користи. Разлог је само тај што би ваш код брзо постао неодржив.

Ако имате овакве проблеме, то значи да је структура ваше продавнице погрешна или да су селектори недовољно прецизни. Треба да дођете до новог круга моделирања.

Препоручујем ове сјајне смернице. Промовише енкапсулацију продавница по контејнеру високог нивоа са глобалним подручјем за кључне структуре података које се протежу у целој апликацији. Ово је прилично сигуран приступ како бисте избегли грешке у моделирању продавница.

Хвала за читање! Ако вам се свидело, притисните дугме за пљескање испод. Помаже другим људима да виде причу.