React 钩子常量的 useMemo 与 useState [英] useMemo vs useState for React hooks constants

查看:29
本文介绍了React 钩子常量的 useMemo 与 useState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 React 钩子定义计算(初始化)的常量可以通过两种看起来功能等效的方式来执行.我不想讨论这个用例,但我只想说,在某些情况下,可以从初始 props 或预期不会改变的状态派生出一个常量值(想想路由数据、绑定调度等).

Defining a calculated (initialized) constant using React hooks can be performed in two ways that seem functionally equivalent. I don't want to get into the use cases for this, but suffice to say that there are cases where a constant value can be derived from initial props or state that isn't expected to change (think route data, bound dispatch, etc).

首先,useState

const [calculatedConstant] = useState(calculateConstantFactory);

二、useMemo

const calculatedConstant = useMemo(calculateConstantFactory, []);

这两个看起来在功能上是等效的,但是如果不阅读源代码,我不确定在性能或其他考虑方面哪个更好.

Both of these seem functionally equivalent, but without reading the source code, I'm not sure which is better in terms of performance or other considerations.

有没有人做过这方面的工作?你会使用哪个,为什么?

Has anyone done the leg work on this? Which would you use and why?

另外,我知道有些人会因为状态可以被认为是恒定的"的假设而退缩.我不知道该告诉你什么.但即使没有状态,我也可能想在一个完全没有状态的组件中定义一个常量,例如,创建一个不会改变的 JSX 块.

Also, I know some people will recoil at the assumption that state can be "considered constant". I'm not sure what to tell you there. But even without state, I may want to define a constant within a component that has no state at all, for example, creating a block of JSX that doesn't change.

我可以在组件外部定义它,但是它会消耗内存,即使有问题的组件没有在应用程序的任何地方实例化.为了解决这个问题,我必须创建一个记忆功能,然后手动释放内部记忆状态.对于钩子免费提供给我们的东西来说,这真是太麻烦了.

I could define this outside of the component, but then it's consuming memory, even when the component in question is not instantiated anywhere in the app. To fix this, I would have to create a memoization function and then manually release the internal memoized state. That's an awful lot of hassle for something hooks give us for free.

添加了本讨论中讨论的方法的示例.https://codesandbox.io/s/cranky-platform-2b15l

Added examples of the approaches talked about in this discussion. https://codesandbox.io/s/cranky-platform-2b15l

推荐答案

你可以信赖关于 useMemo 作为性能优化,而不是作为语义保证

意思是,语义上useMemo 不是正确的方法;你使用它的原因是错误的.因此,即使它现在按预期工作,但您使用不当,将来可能会导致不可预测的行为.

Meaning, semantically useMemo is not the correct approach; you are using it for the wrong reason. So even though it works as intended now, you are using it incorrectly and it could lead to unpredictable behavior in the future.

useState 仅当您不希望在计算值时阻止渲染时才是正确的选择.

useState is only the correct choice if you don't want your rendering to be blocked while the value is being computed.

如果在组件的第一次渲染中不需要该值,则可以将 useRefuseEffect 一起使用:

If the value isn't needed in the first render of the component, you could use useRef and useEffect together:

const calculatedConstant = useRef(null);

useEffect(() => {
  calculatedConstant.current = calculateConstantFactory()
}, [])

// use the value in calcaulatedConstant.current

这与在 componentDidMount 中初始化实例字段相同.并且在运行工厂函数时它不会阻止您的布局/绘制.在性能方面,我怀疑任何基准测试都会显示出显着差异.

This is the same as initializing an instance field in componentDidMount. And it doesn't block your layout / paint while the factory function is being run. Performance-wise, I doubt any benchmark would show a significant difference.

问题在于初始化 ref 后,组件不会更新以反映该值(这是 ref 的全部目的).

The problem is that after initializing the ref, the component won't update to reflect this value (which is the whole purpose of a ref).

如果您绝对需要在组件的第一次渲染中使用该值,您可以这样做:

If you absolutely need the value to be used on the component's first render, you can do this:

const calculatedConstant = useRef(null);

if (!calculatedConstant.current) {
  calculatedConstant.current = calculateConstantFactory();
}
// use the value in calculatedConstant.current;

在设置值之前,这将阻止您的组件呈现.

This one will block your component from rendering before the value is set up.

如果你不想渲染被阻塞,你需要 useStateuseEffect :

If you don't want rendering to be blocked, you need useState together with useEffect:

const [calculated, setCalculated] = useState();

useEffect(() => {
  setCalculated(calculateConstantFactory())
}, [])

// use the value in calculated

基本上,如果您需要组件重新渲染自身:使用 state.如果没有必要,请使用参考.

Basically if you need the component to re-render itself: use state. If that's not necessary, use a ref.

这篇关于React 钩子常量的 useMemo 与 useState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆