Skip to content

useForceUpdate

Описание

useForceUpdate — хук, возвращающий функцию, которая принудительно инициирует повторный рендер компонента. Опционально можно передать колбэк, который выполнится перед тем, как будет запланирован ререндер.


Сигнатура

ts
function useForceUpdate(): (onBeforeUpdate?: () => void) => void;
  • Возвращает
    • Функцию forceUpdate(onBeforeUpdate?), которая инициирует повторный рендер. Если передан onBeforeUpdate, он будет вызван синхронно перед обновлением.

Примеры

1) Принудительное обновление после императивной мутации

tsx
import { useRef } from 'react';
import { useForceUpdate } from '@webeach/react-hooks';

export function RefCounter() {
  const forceUpdate = useForceUpdate();
  const countRef = useRef(0);

  const increment = () => {
    countRef.current += 1; // императивная мутация вне React‑state
    forceUpdate(); // отобразить новое значение
  };

  return <button onClick={increment}>count = {countRef.current}</button>;
}

2) Колбэк перед обновлением (лог/очистка/синхронизация)

tsx
import { useForceUpdate } from '@webeach/react-hooks';

export function WithCallback() {
  const forceUpdate = useForceUpdate();

  const handleClick = () => {
    forceUpdate(() => {
      console.log('Перед повторным рендером');
    });
  };

  return <button onClick={() => handleClick()}>Refresh</button>;
}

Поведение

  1. Стабильность ссылки

    • Возвращаемая функция стабильна между рендерами; её безопасно указывать в зависимостях эффектов и колбэков.
  2. Вызов onBeforeUpdate

    • Если передан onBeforeUpdate, он выполняется синхронно до планирования повторного рендера.
  3. Батчинг обновлений

    • Несколько вызовов в одном тике могут быть объединены React в один ререндер.
  4. Назначение

    • Подходит для синхронизации UI с внешними императивными изменениями, которые не отражены в React‑состоянии.

Когда использовать

  • Интеграция с императивными/внешними API (виджеты, редакторы, карты), когда изменяется внешний объект и нужно «подтянуть» UI.
  • Редкие «мостики» в случаях, где перевод на чистое React‑состояние невозможен/затруднён.

Когда не использовать

  • Если можно хранить и менять данные в React‑состоянии — используйте useState/useReducer/контекст.
  • Для внешних стореджей/эмиттеров предпочтительнее useSyncExternalStore (или подписка + состояние) вместо принудительных ререндеров.

Частые ошибки

  1. Передача forceUpdate напрямую как обработчика события

    • Конструкция onClick={forceUpdate} приведёт к тому, что объект события будет передан как onBeforeUpdate и вызовется как функция, что вызовет ошибку. Используйте обёртку: onClick={() => forceUpdate()} или передавайте корректный колбэк: onClick={() => forceUpdate(() => {/* ... */})}.
  2. Бесконечные обновления из эффекта

    • Вызов forceUpdate() внутри эффекта без условий приведёт к циклу перерисовок. Добавляйте охранные условия/зависимости.
  3. Ожидание «после‑рендер» эффекта

    • onBeforeUpdate исполняется до обновления. Для логики «после рендера» используйте useEffect/useLayoutEffect.