reactjs - React hooks 常量的 useMemo 与 useState

标签 reactjs react-hooks

使用 React hook 定义计算(初始化)常量可以通过两种功能相同的方式执行。我不想讨论这个用例,但足以说明,在某些情况下,可以从初始 props 或状态中派生出一个常量值,而这些值预计不会改变(想想路由数据、绑定(bind)调度等) )。

首先,useState

const [calculatedConstant] = useState(calculateConstantFactory);

第二,useMemo

const calculatedConstant = useMemo(calculateConstantFactory, []);

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

有人做过这方面的工作吗?您会使用哪一个?为什么?

此外,我知道有些人会对状态可以“被认为是恒定的”这一假设感到反感。我不知道该告诉你什么。但即使没有状态,我也可能想在根本没有状态的组件中定义一个常量,例如,创建一个不改变的 JSX block 。

我可以在组件外部定义它,但是它会消耗内存,即使相关组件没有在应用程序中的任何地方实例化。为了解决这个问题,我必须创建一个内存函数,然后手动释放内部内存状态。对于 hooks 免费提供给我们的东西来说,这是一个非常大的麻烦。

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

最佳答案

You may rely on useMemo as a performance optimization, not as a semantic guarantee

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

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

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

const calculatedConstant = useRef(null);

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

// use the value in calcaulatedConstant.current

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

问题是,初始化引用后,组件不会更新以反射(reflect)该值(这是引用的全部目的)。

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

const calculatedConstant = useRef(null);

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

这会在设置值之前阻止您的组件呈现。

如果您不想阻止渲染,则需要 useStateuseEffect:

const [calculated, setCalculated] = useState();

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

// use the value in calculated

基本上,如果您需要组件重新渲染自身:使用状态。如果没有必要,请使用引用。

关于reactjs - React hooks 常量的 useMemo 与 useState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57664450/

相关文章:

javascript - React.js JSON 数据更新,但状态不更新,因此 UI 不更新

reactjs - 使用 useState 对路由进行 React 身份验证

javascript - 使用 React hooks 实现 shouldComponentUpdate - 仅渲染子组件一次,但在 props 更改时更改 DOM

javascript - React Native Expo-Camera 录制视频发现问题 User rejected audio permission needed

javascript - react : Setting State for Deeply Nested Objects w/Hooks

javascript - react 组件的正确命名规范

reactjs - React Bootstrap - 条件 OverlayTrigger 的最佳实践

css - 用于 css 和 scss 的 Webpack 加载器

javascript - 将元素插入对象

reactjs - 仅当组件内的图像成功加载时才渲染组件