Этот вопрос проверяет глубокое понимание механизма согласования (reconciliation) в React и роли ключа (key) в этом процессе.
При изменении key у родительского компонента React интерпретирует это как то, что это совершенно новый компонент. Старый экземпляр компонента и все его дочерние элементы будут полностью размонтированы (вызовутся функции очистки в useEffect), а затем будет смонтирован совершенно новый экземпляр с чистым состоянием. Это мощный инструмент для принудительного сброса состояния компонента.
Ключ (key) — это специальный проп, который помогает React определять, какие элементы изменились, добавились или удалились в списке. Он также играет роль в идентификации компонентов.
Когда React встречает компонент с изменившимся key, он запускает следующий процесс:
Размонтирование:
React полностью уничтожает текущий экземпляр компонента и всех его потомков.
Выполняются функции очистки во всех useEffect хуках (возвращаемое значение из useEffect).
Локальное состояние компонента (созданное через useState, useRef) безвозвратно теряется.
Монтирование:
React создает совершенно новый экземпляр компонента "с чистого листа".
Инициализируется новое, начальное состояние.
Выполняется рендер компонента и всех его дочерних элементов.
Вызываются хуки useEffect после монтирования.
Представьте компонент счетчика, состояние которого нужно сбросить при переключении пользователя.
// UserProfile получает разных пользователей и key, равный user.id
function UserProfile({ user }) {
const [messageCount, setMessageCount] = useState(0);
useEffect(() => {
// Эффект для загрузки данных пользователя
console.log('Монтирование или обновление UserProfile для', user.name);
return () => {
console.log('Размонтирование UserProfile для', user.name); // Очистка
};
}, [user.name]);
return (
<div>
<h2>{user.name}</h2>
<p>Сообщений: {messageCount}</p>
<button onClick={() => setMessageCount(c => c + 1)}>+1</button>
</div>
);
}
// Использование:
// <UserProfile key={currentUser.id} user={currentUser} />Если currentUser меняется с {id: 1, name: 'Alice'} на {id: 2, name: 'Bob'}, то key меняется с 1 на 2.
Компонент для Alice размонтируется (состояние messageCount сбросится, выполнится cleanup в useEffect), а затем смонтируется новый компонент для Bob с messageCount = 0.
Изменение key — это сигнал React о том, что элемент/компонент нужно рассматривать как новый, что приводит к полному пересозданию его и всех дочерних элементов. Это полезно для принудительного сброса внутреннего состояния или перезапуска побочных эффектов.