bfr*_*cka 11 reactjs react-hooks
使用 React 钩子定义计算的(初始化的)常量可以通过两种看起来功能等效的方式来执行。我不想讨论这个用例,但我只想说,在某些情况下,可以从初始道具或预期不会改变的状态派生出一个常量值(想想路由数据、绑定调度等)。
第一的, useState
const [calculatedConstant] = useState(calculateConstantFactory);
Run Code Online (Sandbox Code Playgroud)
第二, useMemo
const calculatedConstant = useMemo(calculateConstantFactory, []);
Run Code Online (Sandbox Code Playgroud)
这两个看起来在功能上是等效的,但是如果不阅读源代码,我不确定在性能或其他考虑方面哪个更好。
有没有人做过这方面的工作?你会使用哪个,为什么?
另外,我知道有些人会因为状态可以“被认为是恒定的”的假设而退缩。我不知道该告诉你什么。但即使没有状态,我也可能想在一个完全没有状态的组件中定义一个常量,例如,创建一个不会改变的 JSX 块。
我可以在组件之外定义它,但是它会消耗内存,即使有问题的组件没有在应用程序的任何地方实例化。为了解决这个问题,我必须创建一个记忆功能,然后手动释放内部记忆状态。对于钩子免费提供给我们的东西来说,这真是太麻烦了。
编辑:添加了本讨论中讨论的方法的示例。 https://codesandbox.io/s/cranky-platform-2b15l
你可以依赖 useMemo 作为性能优化,而不是作为语义保证
意思是,语义useMemo上不是正确的方法;你使用它的原因是错误的。因此,即使它现在按预期工作,但您使用它的方式不正确,将来可能会导致不可预测的行为。
useState 如果您不希望在计算值时阻止渲染,则仅是正确的选择。
如果在组件的第一次渲染中不需要该值,则可以一起使用useRef和useEffect:
const calculatedConstant = useRef(null);
useEffect(() => {
calculatedConstant.current = calculateConstantFactory()
}, [])
// use the value in calcaulatedConstant.current
Run Code Online (Sandbox Code Playgroud)
这与在 中初始化实例字段相同componentDidMount。并且在运行工厂函数时它不会阻止您的布局/绘制。在性能方面,我怀疑任何基准测试都会显示出显着差异。
问题是在初始化 ref 后,组件不会更新以反映该值(这是 ref 的全部目的)。
如果您绝对需要在组件的第一次渲染中使用该值,您可以这样做:
const calculatedConstant = useRef(null);
if (!calculatedConstant.current) {
calculatedConstant.current = calculateConstantFactory();
}
// use the value in calculatedConstant.current;
Run Code Online (Sandbox Code Playgroud)
这将阻止您的组件在设置值之前呈现。
如果您不想阻止渲染,则需要useState与useEffect:
const [calculated, setCalculated] = useState();
useEffect(() => {
setCalculated(calculateConstantFactory())
}, [])
// use the value in calculated
Run Code Online (Sandbox Code Playgroud)
基本上,如果您需要组件重新渲染自身:使用 state。如果没有必要,请使用参考。
| 归档时间: |
|
| 查看次数: |
2873 次 |
| 最近记录: |