如果没有前向引用,对如何创建引用感到困惑?

Posted

技术标签:

【中文标题】如果没有前向引用,对如何创建引用感到困惑?【英文标题】:Confused about how to create a ref if there is no forward ref? 【发布时间】:2021-11-06 16:33:32 【问题描述】:

一共有三个选项,我不知道哪个最好。

//@ts-nocheck
import React,  useEffect, useRef  from "react";

export const Child = React.forwardRef((props, ref) => 
  console.log("ref: ", ref);

  // option 1
  // const divRef = ref || React.createRef();

  // option 2, it's same with option 3?
  // const _ref = useRef(null);
  // const divRef = ref || _ref;

  // option 3, one line
  const divRef = useRef(ref?.current);

  useEffect(() => 
    console.log("divRef: ", divRef.current);
  , []);

  return <div ref=divRef>child</div>;
);

Parent 组件内使用Child 组件:

const Parent = () => (
  <div>
    <Child />
  </div>
);
render(<Parent />);

如您所见,Parent 组件没有创建并将引用传递给Child。逻辑是如果Parent传递了ref,就使用它,如果没有,在Child组件中创建一个

当我运行它并检查控制台日志时,所有这些似乎都是正确的,因为我可以获得divRef

divRef:  <ref *1> htmlDivElement ...

【问题讨论】:

【参考方案1】:

您可以轻松关闭第一个和第三个选项,因为第一个 (createRef) 会在每次渲染时创建一个新的引用,而第三个选项 useRef(ref?.current) 不支持函数引用。

所以第二个选项将允许外部或内部引用,并且还支持外部函数引用:

export const Child = React.forwardRef((props, ref) => 
  const _ref = useRef(null);
  const divRef = ref || _ref;

  useEffect(() => 
    console.log("divRef: ", divRef.current);
  , []);

  return <div ref=divRef>child</div>;
);

【讨论】:

【参考方案2】:

虽然它们在性能方面并没有太大的不同,也没有那么重要,但我会选择Option 1,原因如下:

使用选项 2:useRef 将被调用,无论父项的 ref 是否存在。 使用选项 3:如果再次引用 ref?.current 已经存在,则无需创建另一个 ref 最后选项1:如果左侧为真,|| 的右侧基本上不会调用。

无论如何,你不应该在a few reasons的功能组件中使用createRef


或者我可能会错过一些东西,很高兴收到任何意见。

【讨论】:

以上是关于如果没有前向引用,对如何创建引用感到困惑?的主要内容,如果未能解决你的问题,请参考以下文章

用强弱自我打破保留周期

对c#中的引用传递和值传递感到困惑

odoo以编程方式添加采购订单(rfq)

对Sync的性能影响感到困惑

母版页的相对路径让我感到困惑

对 Java 的按值传递和不变性感到困惑