有没有办法使用React Hooks API模拟构造函数代码的运行频率?

时间:2019-04-18 16:28:04

标签: reactjs react-hooks

有时候,我发现将一些代码放置在React类组件的constructor中,一次执行一次处理(在实例化组件时),并能够始终引用结果是很有用的。现在有办法使用React Hooks API对功能组件执行此操作吗?

示例:

constructor(props) {
    super(props);
    const componentFactory = createComponentFactory(props.context);
    this.components = props.components.map(componentFactory);

2 个答案:

答案 0 :(得分:1)

useEffect仅可用于运行一次代码,但这在组件安装时发生,因此它与componentDidMount相对,而不是构造函数:

let components = useRef();

useEffect(() => {
  components.current = props.components.map(createComponentFactory(props.context))
}, []);
// components.current === null
// on first render

useMemo可用于在第一次渲染时运行一次代码:

const components = useMemo(
  () => props.components.map(createComponentFactory(props.context)),
  []
);

不能保证在以后的React版本中运行一次代码:

  

您可能依赖useMemo作为性能优化,而不是语义保证。将来,React可能会选择“忘记”一些以前记忆的值,并在下一次渲染时重新计算它们,例如释放屏幕外组件的内存。编写代码,使其在不使用useMemo的情况下仍然可以正常工作-然后添加它以优化性能。

useState也可以用于在第一次渲染时运行一次代码:

const [components] = useState(
  () => props.components.map(createComponentFactory(props.context))
);

由于其他选项的局限性,最后一个选项可以被视为实现此目的的首选方法。

答案 1 :(得分:1)

您似乎想要一些实例变量。

您可以使用useRef()钩子来做到这一点。

Docs: Hooks API

  

从本质上讲,useRef 就像一个“盒子”,可以在其.current属性中保留可变值

     

您可能最熟悉refs作为访问DOM的一种方式。如果您将ref对象传递给React,只要该节点发生更改,React就会将其.current属性设置为相应的DOM节点。

     

但是,useRef()不仅对ref属性有用。 与在类中使用实例字段的方式类似,可以方便地保留任何可变值。

Docs: Hooks FAQ

  

是否存在实例变量之类的东西?

     

是的! useRef()钩不仅用于DOM引用。 “ ref”对象是一个通用容器,其当前属性是可变的,并且可以保存任何值,类似于类的实例属性。