useEffect
и setState
будут вызывать дополнительные рендеры при каждом изменении: первый рендер будет "отставать" от устаревших данных, а затем сразу же ставит в очередь дополнительный рендеринг с новыми данными.
Предположим, что у нас есть:
function expensiveCalculation(x) { return x + 1; }; // Maybe I'm running this on a literal potato
Предположим, что numberProp
изначально равно 0:
- Версия
useMemo
немедленно отображает 1
. - Версия
useEffect
отрисовывает null
, затем после рендеринга компонента запускается эффект, изменяется состояние и ставится в очередь новый рендеринг с 1
.
Затем, если мы изменимnumberProp
до 2:
-
useMemo
запускается и 3
визуализируется. - Версия
useEffect
запускается и снова отображает 1
, затем эффекттриггеры и компонент перезапускается с правильным значением 3
.
С точки зрения частоты выполнения expensiveCalculation
, оба имеют идентичное поведение, но версия useEffect
вызывает вдвое большерендеринг, который плохо влияет на производительность по другим причинам.
Плюс, версия useMemo
просто чище и читабельнее, ИМО.Он не вносит ненужного изменчивого состояния и имеет меньше движущихся частей.
Так что вам лучше просто использовать useMemo
здесь.