Реагировать на ключи

React поддерживает копию HTML DOM, используя виртуальный DOM. Когда вы каким-либо образом изменяете HTML DOM, React использует виртуальный DOM для сравнения. Это отличная функция React, поскольку она не требует создания, удаления или обновления узлов HTML при каждом изменении DOM. Рендерер React пытается внести как можно меньше изменений. Например, если вы измените атрибут узла HTML, React не удалит старый узел, а создаст новый. Сравнивая виртуальный DOM, он приходит к выводу, что изменился только атрибут, поэтому он обновляет его без каких-либо ненужных манипуляций с HTML DOM. Такое поведение прекрасно, но единственная проблема заключается в том, что средство визуализации React предполагает, что дочерние узлы изменились, если родительский узел каким-либо образом изменяется, поэтому он уничтожит дочерние узлы и воссоздаст узлы с нуля.

Ключ React — это атрибут HTML с именем key. Вы всегда должны использовать ключ, где это возможно, потому что средство визуализации React использует ключи, чтобы определить, следует ли уничтожать и воссоздавать дочерний узел. Давайте представим, что мы определили HTML-узел с атрибутом key, значение которого равно "x". Если его родитель будет обновлен, React просто сравнит виртуальный DOM при проверке измененных дочерних узлов и сделает вывод, что дочерний элемент не нужно обновлять, поскольку атрибут key имеет то же значение. Таким образом, мы сохранили как минимум 2 манипуляции с HTML DOM.

Реагировать на фрагмент

Вы когда-нибудь возвращали div как корневой элемент компонента только для того, чтобы вернуть только один элемент, как требуется?
Ну, вы можете просто обернуть компонент внутри компонента React.Fragment. Позор тебе…

Компонент Fragment позволяет вам возвращать несколько элементов в методе рендеринга без фактического создания дополнительного элемента DOM.
Этот компонент также можно использовать с сокращением ‹›‹/› синтаксис. Этот синтаксис не принимает никаких атрибутов, включая ключи. Поэтому, если вам нужно определить атрибуты, используйте Фрагмент.

React.forwardRef

Компоненты класса React могут передавать ссылку на элементы DOM в качестве реквизита. Но когда дело доходит до функциональных компонентов, лучший способ сделать это — использовать React.forwardRef. Переадресация ссылок — это, по сути, функция, которая позволяет компонентам передавать ссылку на элемент дочернему элементу. Давайте посмотрим на пример.

В родительском компоненте у нас есть HTML-кнопка с обработчиком кликов.
Parent создает экземпляр ссылки, вызывая React.createRef(). В функции обработчика кликов мы присваиваем значение элемента, на который указывает ссылка.

const Parent = () => {
  const ref = React.createRef();
function handleClick() {
    const { value } = ref.current;
    ref.current.value = value === "" ? 
                        "I've just populated input ?!?" 
                        : "";
  }
  
  return (
    <div>
      <button onClick={handleClick}>
          Click me to populate input
      </button>
      <Child ref={ref} spanContent="span content" />
    </div>
    );
};

Дочерний компонент — это функция, переданная React.forwardRef в качестве первого аргумента, второй аргумент — ссылка, переданная родительским компонентом. Дочерний элемент отображает входные данные, атрибут ref которых назначен проходящей ссылке.

Таким образом, родительский компонент может легко манипулировать элементом ввода HTML, содержащимся в дочерней модели DOM.

const Child = React.forwardRef((props, ref) => (
  <div>
  I am element with blank input <input ref={ref} />
  </div>
 )
)

Реагировать Портал

React Portal позволяет отображать дочерние элементы в узле DOM, невидимом для дочерних элементов. Таким образом, вы можете динамически изменять структуру основного HTML-документа изнутри. Поначалу это может показаться запутанным, потому что это противоположно большинству вещей, которые вы, вероятно, делали до сих пор.

React API предоставляет функцию ReactDOM.createPortal(), первым аргументом которой является компонент, который вы хотите визуализировать, а вторым аргументом является любой действительный узел DOM, независимо от его местоположения в DOM.

React Portal ведет себя так же, как обычный дочерний элемент. Вы можете использовать все функции React, такие как пример React.Context, как обычно. Пузырьковые события передаются родителю в HTML DOM, а не родителю в коде React.

Вы когда-нибудь хотели создать какой-то модальный/диалоговый компонент, который должен иметь самый высокий z-индекс в вашем приложении на данный момент? Часто бывает, что он отображается компонентом, который имеет собственную область z-index, что может привести к тому, что некоторые другие компоненты в приложении, такие как заголовок для примера, переполнят ваш компонент. С помощью React Portal вы можете легко прикрепить свой компонент к элементу с соответствующей областью z-index. Этот пример демонстрирует упомянутый случай.

const ModalComponent = ({content}) => 
                       (<div id="trust_me_imma_modal">
                          {content}
                        </div>)
const Modal = props => { 
  const headerElement = document.querySelector("header")
  return ReactDOM.createPortal(
                  <ModalComponent {...props}  />,
                  headerElement)
  }

React.useMemo

Я знаю, что это заголовок DOM-сахара, но позвольте мне объяснить, почему я считаю useMemohook сахаром DOM.

const memoizedValue = useMemo(
                      () => computeExpensiveValue(a, b), [a, b]);

Это функция, которая исключает обратный вызов и массив зависимостей. Функция обратного вызова будет вызываться только в том случае, если некоторые из зависимостей изменились. Таким образом, это помогает с оптимизацией, потому что мы избегаем дорогостоящих вычислений при каждом рендеринге. Используя его вместо хука useState, мы получаем более быстрый рендеринг DOM, из-за этого я считаю его функцией оптимизации рендеринга DOM.