理解:警告:无法为功能组件提供引用

时间:2020-04-27 02:19:04

标签: javascript reactjs ref react-forwardref

我知道ref用于直接访问DOM元素,而不会更改状态。我读到不可能给功能组件提供引用,因为它们没有状态。

引用不能附加到功能组件。虽然,我们可以 定义引用并将它们附加到DOM元素或类 组件。最重要的是-功能组件没有 实例,因此您无法引用它们。

摘自:https://blog.logrocket.com/cleaning-up-the-dom-with-forwardref-in-react/

我还是不明白。

我正在使用Ant Design(https://ant.design/components/tooltip/)的Tooltip组件,Button组件和自定义CircleButton组件。

给出以下JSX:

<Tooltip placement="left" title={"Lock slot"}>
  <CircleButton onClick={() => execute(client.close)} icon={<LockOutlined />} disabled={loading} />
</Tooltip>

还有我的CircleButton组件。 以此方式使用,它将生成警告

const CircleButton = (props) => // gives the warning
  <Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />

警告:不能为功能组件提供引用。尝试访问 该裁判将失败。您是要使用React.forwardRef()吗?

请注意,尽管有警告,但一切都会按预期进行。

如果我按如下方式进行编辑,它将可以正常工作,为什么?

const CircleButton = forwardRef((props, ref) => // doesn't give the warning
  <div ref={ref}>
    <Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />
  </div>)

div组件是否有状态?我不明白forwardRef是否在做一些魔术并为div元素创建状态?

为什么如果我将ref传递给Button组件,它仍然会发出警告?

const CircleButton = forwardRef((props, ref) => // gives the warning
  <Button ref={ref} shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />)

如果我小时候直接通过antd Button,就可以了。但这是因为我认为antd按钮具有某种状态,因此可以具有引用。

<Tooltip placement="left" title={"Lock slot"}> // doesn't give the warning
  <Button shape="circle" size="small" style={{ marginRight: "8px" }} />
</Tooltip>

2 个答案:

答案 0 :(得分:2)

作为警告状态,如果不使用forwardRef,则不能将ref分配给功能组件

为了访问任何组件的引用,要求创建该组件的实例,并且仅为类组件创建一个实例,同时调用或调用功能组件

从v16.8.0起,React引入了一个名为useRef的API,该API还允许您在功能组件内创建引用,该引用也可以在HTML节点,类组件或用forwardRef包装的功能组件上使用

要实现与带有ref的类组件中相同的行为,可以将forwardRefuseImperativeHandle挂钩一起使用,以将功能组件中的某些功能或状态显示给父对象

const CircleButton = forwardRef((props, ref) => {
  const someFunction = () =>{}
  useImperativeHandle(ref, () => ({
     someFunc
  }));

  return (
    <div>
        <Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />
   </div>

  )
}

答案 1 :(得分:1)

请不要混淆,首先这与功能或类组件无关,这意味着您可以同时使用ref,react 16+具有钩子useRef,因此您也可以将ref用于功能组件,

回答您的问题,antd Button有他们的own ref,因此在您的案例Tooltip中,它忽略了父组件传递的引用,为什么您没有看到任何警告为此,但是当您使用自己的组件时,必须花费ref传递的Tooltip

而且,您仍然不想使用React.forwordRef,而只是在将props传递给组件时忽略它。但是您将无法获得antd受控组件提供的某些功能