可以使用两种在功能上等效的方式来执行使用React钩子定义计算的(初始化的)常量。我不想进入用例,但足以说在某些情况下,可以从初始支持或状态中得出恒定值,而该状态不会发生变化(请考虑路线数据,绑定调度等)。 )。
首先,useState
const [calculatedConstant] = useState(calculateConstantFactory);
第二,useMemo
const calculatedConstant = useMemo(calculateConstantFactory, []);
这两者在功能上似乎是等效的,但是在不阅读源代码的情况下,我不确定在性能或其他考虑因素上哪个更好。
有人在这方面做过腿工作吗?您将使用哪个?为什么?
此外,我知道有些人会在状态可以“被认为是常数”的假设下反冲。我不确定在那告诉你什么。但是即使没有状态,我也可能想在完全没有状态的组件中定义一个常量,例如,创建一个不变的JSX块。
我可以在组件外部定义它,但是即使在应用程序中没有实例化所讨论的组件时,它也会消耗内存。要解决此问题,我必须创建一个记忆功能,然后手动释放内部记忆状态。钩子免费提供给我们的东西真是太麻烦了。
编辑:添加了本讨论中讨论的方法的示例。 https://codesandbox.io/s/cranky-platform-2b15l
答案 0 :(得分:0)
You may rely on useMemo as a performance optimization, not as a semantic guarantee
语义上useMemo
的含义不正确;您出于错误原因使用它。因此,即使它现在已经按预期工作了,但您使用它的方式还是不正确,将来可能会导致无法预测的行为。
useState
仅当您不希望在计算值时阻止渲染时才是正确的选择。
如果在组件的第一次渲染中不需要该值,则可以一起使用useRef
和useEffect
:
const calculatedConstant = useRef(null);
useEffect(() => {
calculatedConstant.current = calculateConstantFactory()
}, [])
// use the value in calcaulatedConstant.current
在语义上,这与在componentDidMount
中初始化实例字段相同。并且在运行工厂功能时,它不会阻止您的布局/绘制。在性能方面,我怀疑任何基准测试都不会显示出显着差异。
问题在于初始化ref后,组件将不会更新以反映该值(这是ref的全部目的)。
如果您绝对需要在组件的第一个渲染上使用该值,则可以执行以下操作:
const calculatedConstant = useRef(null);
if (!calculatedConstant.current) {
calculatedConstant.current = calculateConstantFactory();
}
// use the value in calculatedConstant.current;
这将在设置值之前阻止您的组件渲染。
如果您不想阻止渲染,则需要useState
和useEffect
:
const [calculated, setCalculated] = useState();
useEffect(() => {
setCalculated(calculateConstantFactory())
}, [])
// use the value in calculated
基本上,如果您需要组件重新呈现自身,请使用state。如果不需要,请使用参考。