Есть ли способ эмулировать частоту выполнения кода конструктора с помощью React Hooks API? - PullRequest
1 голос
/ 18 апреля 2019

Иногда мне показалось полезным поместить некоторый код в constructor компонента класса React, выполнить некоторую обработку один раз (когда создается экземпляр компонента) и иметь возможность ссылаться на результат повсюду. Есть ли теперь способ сделать это с помощью функционального компонента, использующего React Hooks API?

пример:

constructor(props) {
    super(props);
    const componentFactory = createComponentFactory(props.context);
    this.components = props.components.map(componentFactory);

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Похоже, вы хотите что-то вроде переменных экземпляра.

Вы можете сделать это, используя хук useRef().

Docs: Hooks API

По сути, useRef подобен «ящику», который может содержать изменяемое значение в своем свойстве .current.

Возможно, вы знакомы с ссылками в первую очередь как способ доступаДОМ.Если вы передадите объект ref в React, React будет устанавливать его свойство .current для соответствующего узла DOM при каждом изменении этого узла.

Однако useRef () полезен не только для атрибута ref. Это удобно для хранения любого изменяемого значения, похожего на то, как вы используете поля экземпляров в классах.

Документы: FAQ по хукам

Есть ли что-то вроде переменных экземпляра?

Да!Хук useRef () предназначен не только для ссылок DOM.Объект «ref» - ​​это универсальный контейнер, текущее свойство которого является изменяемым и может содержать любое значение, аналогичное свойству экземпляра в классе.

1 голос
/ 18 апреля 2019

useEffect можно использовать для запуска кода один раз, но это происходит при монтировании компонента, поэтому это аналог componentDidMount, а не конструктор:

let components = useRef();

useEffect(() => {
  components.current = props.components.map(createComponentFactory(props.context))
}, []);
// components.current === null
// on first render

useMemo можно использовать длявыполнить код один раз при первом рендеринге:

const components = useMemo(
  () => props.components.map(createComponentFactory(props.context)),
  []
);

Не гарантированно запускать код один раз в будущих версиях React:

Вы можете положиться на использованиеMemo в качестве оптимизации производительностине как семантическая гарантия.В будущем React может решить «забыть» некоторые ранее запомненные значения и пересчитать их при следующем рендеринге, например, чтобы освободить память для компонентов вне экрана.Напишите свой код, чтобы он по-прежнему работал без useMemo, а затем добавьте его для оптимизации производительности.

useState можно использовать для однократного запуска кода при первом рендеринге:

const [components] = useState(
  () => props.components.map(createComponentFactory(props.context))
);

Из-за ограничений других опций последний вариант можно считать предпочтительным способом сделать это.

...