Как вы можете убедить React в том, что два варианта использования компонента нуждаются в собственном индивидуальном состоянии? С ключами, конечно!

Подход React может быть довольно сложным, и вы можете столкнуться с неожиданным поведением или даже незначительными ошибками. Избавиться от таких ошибок может быть довольно сложно, если вы не знакомы с их причиной.

Особая ошибка возникает, когда вы условно визуализируете один и тот же компонент с разными свойствами. Подробно изучите эту ошибку и узнайте, как использовать ключи React для ее решения.

Компоненты React не всегда независимы

Его простой синтаксис является одной из основных причин вы должны изучить React. Но, несмотря на множество достоинств, фреймворк не лишен багов.

Ошибка, о которой вы узнаете здесь, возникает, когда вы условно визуализируете один и тот же компонент, но передаете ему разные реквизиты.

В подобных случаях React будет считать, что два компонента одинаковы, поэтому не будет утруждать себя визуализацией второго компонента. В результате любое состояние, которое вы определяете в первом компоненте, будет сохраняться между рендерингами.

instagram viewer

Для демонстрации возьмем этот пример. Во-первых, у вас есть следующее Прилавок компонент:

import { useState, useEffect } from"react"

exportfunctionCounter({name}) {
const [count, setCount] = useState(0)

return(


{name}</div>

Этот Прилавок компонент принимает имя от родителя через деструктурирование объекта, что является способом использовать реквизит в React. Затем он отображает имя в. Он также возвращает две кнопки: одну для уменьшения считать в состоянии, а другой, чтобы увеличить его.

Имейте в виду, что в приведенном выше коде нет ничего плохого. Ошибка связана со следующим блоком кода (компонент приложения), в котором используется счетчик:

import { useState } from"react"
import { Counter } from"./Counter"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return(


{ isKingsley? <Countername="Kingsley" />: <Countername="Sally" /> }


По умолчанию приведенный выше код отображает счетчик с именем Kingsley. Если вы увеличите счетчик до пяти и нажмете кнопку Менять кнопку, он отобразит второй счетчик с именем Sally.

Но проблема в том, что счетчик не сбрасывается в состояние нуля по умолчанию после того, как вы их поменяли местами.

Эта ошибка возникает из-за того, что оба состояния отображают одни и те же элементы в одном и том же порядке. React не знает, что счетчик «Кингсли» отличается от счетчика «Салли». Единственная разница заключается в имя prop, но, к сожалению, React не использует это для различения элементов.

Вы можете обойти эту проблему двумя способами. Во-первых, изменив свой DOM и сделав два дерева разными. Это требует, чтобы вы поняли что такое ДОМ. Например, вы можете обернуть первый счетчик внутри элемент, а второй внутри элемент:

import { useState } from"react"
import { Counter } from"./Counter"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return (


{ isKingsley?
(<div>
"Kingsley" />
</div>)
:
(<section>
"Sally" />
</section>)
}


Если вы увеличите значение счетчика «Кингсли» и нажмете Менять, состояние сбрасывается в 0. Опять же, это происходит потому, что структура двух деревьев DOM различна.

Когда Кингсли переменная истинный, структура будет див >див > Прилавок (div, содержащий div, содержащий счетчик). Когда вы меняете состояние счетчика с помощью кнопки, структура становится див > раздел > Прилавок. Из-за этого несоответствия React автоматически отображает новый счетчик с состоянием сброса.

Возможно, вам не всегда захочется изменять структуру разметки таким образом. Второй способ устранения этой ошибки позволяет избежать необходимости в другой разметке.

Использование ключей для рендеринга нового компонента

Ключи позволяют React различать элементы в процессе рендеринга. Итак, если у вас есть два совершенно одинаковых элемента, и вы хотите сообщить React, что один отличается от другого, вам нужно установить уникальный ключевой атрибут для каждого элемента.

Добавьте ключ к каждому счетчику, например:

import { useState } from"react"
import { Counter } from"./Counter"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return(


{ isKingsley?
"Kingsley" name="Kingsley" />:
"Sally" name="Sally" />
}


Теперь, когда вы увеличиваете значение счетчика «Кингсли» и нажимаете Менять, React отображает новый счетчик и сбрасывает состояние на ноль.

Вы также должны использовать ключи при рендеринге массива элементов одного типа, поскольку React не будет знать разницу между каждым элементом.

exportdefaultfunctionApp() {
const names = ["Kingsley", "John", "Ahmed"]

return(


{ names.map((name, index) => {
return<Counterkey={index}name={name} />
})}
</div>
)
}

Когда вы назначаете ключи, React свяжет отдельный счетчик с каждым элементом. Таким образом, он может отражать любые изменения, которые вы вносите в массив.

Еще один вариант использования расширенного ключа

Вы также можете использовать ключи, чтобы связать элемент с другим элементом. Например, вы можете захотеть связать элемент ввода с различными элементами в зависимости от значения переменной состояния.

Чтобы продемонстрировать, настройте компонент App:

import { useState } from"react"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return(


{ isKingsley? <div>Kingsley's Scorediv>: <div>Sally's scorediv> }
"Kingsley": "Sally" } type="number"/>


Теперь каждый раз, когда вы переключаетесь между элементы для Кингсли и Салли, вы автоматически меняете ключевой атрибут ввода между «Кингсли» и «Салли». Это заставит React полностью перерисовывать элемент ввода при каждом нажатии кнопки.

Дополнительные советы по оптимизации приложений React

Оптимизация кода является ключом к созданию приятного пользовательского опыта в вашем веб-приложении или мобильном приложении. Знание различных методов оптимизации может помочь вам получить максимальную отдачу от ваших приложений React.

Самое приятное то, что вы можете применять большинство этих методов оптимизации и к приложениям React Native.