← Усі статті

React useLatest: свіжий стан в async-колбеках без зайвих рендерів

Хук useLatest з @reactuses/core: актуальний ref у layout-ефекті проти застарілих замикань після await, у таймерах і підписках.

React useLatest: свіжий стан в async-колбеках без зайвих рендерів
Зміст

Коротко

Кнопка «Зберегти» ставить статус saved, поки користувач ще друкує: замикання тримає старий text. Стаття на Dev.to розбирає useLatest з @reactuses/core — стабільний ref, який у layout-ефекті завжди вказує на останнє закомічене значення й читається з колбеків після await, таймерів і підписок.

Що сталося

Будь-який колбек, що пережив свій рендер (await, setTimeout, слухач, SDK), бачить props і state того рендера, де його створили. Це нормальне замикання; баг — коли потрібно «зараз», а отримали «тоді».

useLatest(value) повертає стабільний ref: .current оновлюється в isomorphic layout-ефекті, не під час рендера (concurrent-рендеринг може відкинути рендер). У прикладі автозбереження замикання зберігає знімок для відправки, ref — текст після відповіді API, щоб обрати saved або dirty.

Поруч: useEvent / useEffectEvent — для функцій; useLatest — для значень. Типові місця: гонка пошуку в обробнику, карта або WebSocket з порожнім масивом залежностей, тост із паузою при наведенні.

Чому це важливо

«Покласти state в залежності ефекту» часто означає рвати дорогу підписку. Ref дає чесний порожній масив залежностей і свіжі дані всередині. Помилка — читати .current у JSX: для екрана потрібен useState.

На практиці

  1. Після await порівнюйте надісланий знімок із latest.current.
  2. Підписки «один раз» читайте через ref, а не через залежності, що перестворюють клієнт.
  3. Пишіть у ref у layout-ефекті, не в тілі рендера.
  4. Функцію в дитину або ефект — через useEvent; значення в колбек — через useLatest.
  5. Не кладіть ref у залежності «щоб зреагувати» — його identity стабільний.

Підсумок

useLatest — маленький патерн проти застарілих замикань: завжди актуальний із колбека, не тригерить ререндер і не змінює identity. Для UI як і раніше state.