📌 Питання:
Є список:
{users.map((user, index) => (
<UserRow key={index} user={user} />
))}
У
UserRow є локальний state:
function UserRow({ user }) {
const [isEditing, setIsEditing] = useState(false);
return (
<>
<span>{user.name}</span>
<button onClick={() => setIsEditing(true)}>
Edit
</button>
{isEditing && <input />}
</>
);
}
Що може статися після видалення або сортування елементів?
📌 Очікувана відповідь:
index — це позиція елемента, а не його стабільна ідентичність.Наприклад:
До:
Alice Bob Charlie
0 1 2
Після видалення Alice:
Bob Charlie
0 1
React використовує
key, щоб зіставляти елементи між render’ами.Після видалення Alice той самий
key={0} уже належить Bob. Для React це означає, що компонент із key 0 залишився тим самим, хоча на рівні наших даних це вже інший користувач.Через це локальний
state компонента може «переїхати» до іншої сутності.Тому для списків, які можуть змінювати порядок, краще використовувати стабільний ID:
{users.map(user => (
<UserRow key={user.id} user={user} />
))}
📌 Важливий нюанс:
key — це не просто спосіб прибрати warning у консолі.Він допомагає React визначати identity елементів між render’ами та правильно пов‘язувати з ними
state.3. Чи завжди useCallback покращує performance?
📌 Питання:
Чи обов’язково тут потрібен
useCallback?
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('click');
}, []);
return (
<>
<button onClick={() => setCount(c => c + 1)}>
{count}
</button>
<Child onClick={handleClick} />
</>
);
}
const Child = React.memo(function Child({ onClick }) {
return <button onClick={onClick}>Child</button>;
});
📌 Очікувана відповідь:
Не обов‘язково.
useCallback дозволяє зберігати ту саму function reference між render’ами, доки його dependencies не змінилися.У цьому прикладі він може бути корисним разом із
React.memo: Child отримує ту саму reference handleClick, тому незмінний onClick не змушує memoized-компонент render’итися повторно.Але якщо стабільна reference функції ні на що не впливає,
useCallback може бути просто зайвою memoization.Тому не варто автоматично додавати:
useCallback(...)useMemo(...)React.memo(...)до кожного компонента.
📌 А що із сучасним React?
У проєктах із React Compiler багато memoization-оптимізацій React може виконувати автоматично.
Це зменшує потребу вручну додавати
useCallback, useMemo і React.memo лише заради оптимізації render’ів.Тому хороша відповідь на рівні senior звучить приблизно так:
«Спочатку я визначаю, чи потрібна тут memoization взагалі. Якщо проєкт використовує React Compiler, значну частину таких оптимізацій він може виконати автоматично. Ручну memoization додаю, коли для цього є конкретна причина».