有时候,我发现将一些代码放在React类组件的constructor
中,做一些处理(当组件被实例化时)并且能够在整个过程中引用结果时很有用。现在有办法使用React Hooks API使用功能组件吗?
例:
constructor(props) {
super(props);
const componentFactory = createComponentFactory(props.context);
this.components = props.components.map(componentFactory);
看起来你想要像实例变量这样的东西。
你可以使用useRef()
钩子做到这一点。
从本质上讲,useRef就像一个“盒子”,可以在其.current属性中保存一个可变值。
您可能熟悉refs主要是作为访问DOM的一种方式。如果将ref对象传递给React,则只要该节点发生更改,React就会将其.current属性设置为相应的DOM节点。
但是,useRef()比ref属性更有用。保持任何可变值与您在类中使用实例字段的方式类似,这很方便。
是否有类似实例变量的东西?
是! useRef()Hook不仅适用于DOM引用。 “ref”对象是一个通用容器,其当前属性是可变的,可以保存任何值,类似于类上的实例属性。
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))
);
由于其他选项的限制,最后一个选项可被视为执行此操作的首选方法。