Сохранение объекта класса между рендерами через useRef

ref.current сохраняет первоначальный экземпляр, но new MyClass(...) вычисляется при каждом вызове компонента. Поэтому конструктор снова логирует новое время, а ref продолжает хранить старое.

Короткий ответ

Что ответить на собеседовании

ref.current сохраняет первоначальный экземпляр, но new MyClass(...) вычисляется при каждом вызове компонента. Поэтому конструктор снова логирует новое время, а ref продолжает хранить старое.

Подробный разбор

Ответ с пояснениями

Условие

Проведём эксперимент, чтобы увидеть, сохраняет ли хук useRef один и тот же экземпляр класса после каждой перерисовки компонента и меняется ли значение свойства creationTime. В конструкторе и при каждом рендере выводятся соответствующие данные в консоль.

import { useRef, useState } from "react";

class MyClass {
  public creationTime;
  constructor(value: number) {
    this.creationTime = value;
    console.log(value);
  }
}

export default function MyComponent() {
  const classInstanceRef = useRef(new MyClass(new Date().getTime()));
  const [, triggerRender] = useState<Symbol>(Symbol());

  console.log(classInstanceRef.current.creationTime);

  return (
    <div>
      <h1>Hello world</h1>
      <button onClick={() => triggerRender(Symbol())}>
        update state
      </button>
    </div>
  );
}

Ответ

ref.current сохраняет первоначальный экземпляр, но new MyClass(...) вычисляется при каждом вызове компонента. Поэтому конструктор снова логирует новое время, а ref продолжает хранить старое.

Чтобы не создавать выбрасываемые экземпляры, инициализируйте ref при отсутствии значения:

const classInstanceRef = useRef<MyClass | null>(null);
if (classInstanceRef.current === null) {
  classInstanceRef.current = new MyClass(Date.now());
}

При повторных рендерах одного смонтированного экземпляра creationTime не меняется. При новом монтировании создаётся новый объект. В режиме разработки Strict Mode возможны дополнительные вызовы инициализации для проверки чистоты, поэтому конструктор не должен запускать сетевые запросы или необратимые побочные эффекты.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее