Динамический рендеринг компонентов в React

год назад·1 мин. на чтение

В этой статье рассмотрим, как динамически добавлять или удалять компоненты в react.

Во-первых, нам нужно создать два новых компонента, чтобы мы могли использовать их для динамического рендеринга.
// userA.js

import React from "react";

function UserA() {
  return (
    <div>
      <h1>This is user A</h1>
    </div>
  );
}

export default UserA;
// userB.js

import React from "react";

function UserA() {
  return (
    <div>
      <h1>This is user B</h1>
    </div>
  );
}

export default UserB;

Создание динамического компонента

Теперь нам нужно создать динамический компонент, который поможет нам динамически визуализировать другие компоненты на основе пропсов.
// Dynamic.js

import React from "react";
import UserA from "./userA";
import UserB from "./userB";

const components = {
  usera: UserA,
  userb: UserB
};

function DynamicComponent(props) {
  const SelectUser = components[props.user];
  return <SelectUser />;
}

export default DynamicComponent;
В приведенном выше коде мы сначала импортировали два компонента (UserA, UserB), а затем добавили их в объект components. Внутри DynamicComponent мы создали переменную SelectUser и вернули ее. Таким образом, если мы передадим usera в качестве пропса, то отрендерится компонент UserA. Если мы передадим userb в качестве пропса, отрендерится компонент UserB.

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

Давайте теперь воспользуемся нашим динамическим компонентом, импортировав его.
// App.js

import React, { useState } from "react";
import DynamicComponent from "./Dynamic";

function App() {
  const [user, changeUser] = useState("usera");
  return (
    <div>
      {/* изначально отрендерится компонент UserA */}
      <DynamicComponent user={user} />
      <button onClick={() => changeUser("usera")}>Switch user-a</button>
      <button onClick={() => changeUser("userb")}>Switch user-b</button>
    </div>
  );
}

export default App;

Проп key для пересоздания компонента в ReactJS

2 года назад·2 мин. на чтение

Знали ли вы, что проп key может быть полезен не только при рендеринге списка компонентов. Проп key можно использовать и для того чтобы сбросить состояние одного компонента.

Что такое проп key в ReactJS?

Это специальный проп, который может быть добавлен к любому компоненту. Он помогает механизму reconciliation (согласование), упрощая сравнение компонентов. Типичный сценарий использования key - добавление его в компоненты списка. Он нужен для того чтобы React понимал, какой компонент списка был добавлен, удален или изменен.
const notes = [
  {
    id: 1,
    title: 'React hooks',
  },
  {
    id: 2,
    title: 'JSX',
  },
  {
    id: 3,
    title: 'Redux',
  },
];

const NotesList = ({ notes, onClick }) => {
  return (
    <div className="notes-list">
      {notes.map((note) => (
        <p
          className="notes-list__item"
          key={note.id}
          onClick={() => onClick(note)}
        >
          {note.title}
        </p>
      ))}
    </div>
  );
};

Проп key работает и вне списков

Проп key может быть добавлен к абсолютно любому компоненту для того, чтобы сбросить нежелательное состояние этого компонента. Например, в списке заметок есть поле для ввода текста. Если просто добавить это поле и ввести в него текст, то при выборе новой заметки слева - текст будет сохраняться. И, предположим, при выборе заметки мы хотим очистить это поле. список заметок в приложении ReactJS
function App() {
  const [activeNote, setActiveNote] = useState();

  const handleClick = (note) => {
    setActiveNote(note);
  };

  return (
    <div className="notes-container">
      <NotesList notes={notes} onClick={handleClick} />
      <Note title={activeNote?.title} />
    </div>
  );
}
const Note = ({ title }) => {
  const [text, setText] = useState();

  const handleChange = (event) => {
    setText(event.target.value);
  };

  return (
    <div className="note">
      <p>{title}</p>
      <textarea
        className="note-textarea"
        value={text}
        onChange={handleChange}
      />
    </div>
  );
};
Это можно сделать, например, добавив проп text в компонент Note. И далее очищать его при изменении состояния activeNote. Но изменение компонентов может быть невозможным, если мы используем компоненты из third-party библиотеки.

Сброс состояние экземпляра компонента

Проп key помогает React идентифицировать компонент. Его также можно использовать, чтобы сообщить React, что идентификатор компонента изменился и это вызовет полное повторное создание этого компонента. Добавим key={activeNote?.id} к компоненту <Note />.
// ...
  return (
    <div className="notes-container">
      <NotesList notes={notes} onClick={handleClick} />
      <Note title={activeNote?.title} key={activeNote?.id} />
    </div>
  );
}
Теперь, при изменении key React пересоздаст компонент <Note />.

Влияние на производительность

Хотя это хороший прием, который уменьшает количество кода, важно иметь ввиду, что этот подход заставляет React пересоздавать весь экземпляр компонента. В примере выше большая часть компонента <Note /> будет перерисована в любом случае при изменении activeNote. Поэтому в этом случае это достаточно хорошее решение. В реальных приложениях нужно ограничивать добавление key к одиночным компонентам вне списков, а также избегать добавления key на компоненты верхнего уровня. Это может стать причиной проблем с производительностью, которые трудно обнаружить.