理解:警告:不能给函数组件提供引用 [英] Understanding: Warning: Function components cannot be given refs

查看:129
本文介绍了理解:警告:不能给函数组件提供引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 refs 用于直接访问 DOM 元素而不改变状态.我读到无法为功能组件提供引用,因为它们没有状态.

<块引用>

Refs 不能附加到函数组件.虽然,我们可以定义 refs 并将它们附加到 DOM 元素或类组件.底线是——功能组件没有实例,因此您无法引用它们.

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

我还是不明白.

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

鉴于以下 JSX:

还有我的 CircleButton 组件.这样使用,会产生警告.

const CircleButton = (props) =>//给出警告<Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props}/>

<块引用>

警告:不能为函数组件提供引用.尝试访问这个 ref 会失败.你的意思是使用 React.forwardRef() 吗?

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

如果我按如下方式编辑它,它会正常工作,为什么?

const CircleButton = forwardRef((props, ref) =>//不给出警告<div ref={ref}><Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props}/></div>)

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

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

const CircleButton = forwardRef((props, ref) =>//给出警告<Button ref={ref} shape="circle" size="small" style={{ marginRight: "8px" }} {...props}/>)

如果我作为孩子直接传递 antd Button ,它会起作用.但这是因为我认为 antd 按钮有一个状态,因此它可以有 refs.

解决方案

作为警告状态,你不能在没有使用 forwardRef 的情况下将 refs 分配给功能组件

为了能够访问任何组件的引用,需要创建一个组件的实例,并且只为类组件创建一个实例,而调用或调用功能组件>

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

要使用 ref 实现类组件中可用的相同行为,您可以使用 forwardRefuseImperativeHandle 钩子将功能组件中的某些功能或状态暴露给父级

const CircleButton = forwardRef((props, ref) => {const someFunction = () =>{}useImperativeHandle(ref, () => ({someFunc}));返回 (<div><Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props}/>

)}

I know that refs are used to access DOM elements directly without altering the state. I read that it's not possible to give refs to function components because they don't have a state.

Refs cannot be attached to function components. Although, we can define refs and attach them to either DOM elements or class components. The bottom line is — function components do not have instances so you can’t reference them.

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

I still don't understand.

I am using the Tooltip component from Ant Design (https://ant.design/components/tooltip/), the Button component and a custom CircleButton component.

Given the following JSX:

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

And my CircleButton component. Used like this, it will generate the warning.

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

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Note that everything works as expected despite the warning.

If I edit it as follows though, it will work fine, why?

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

Does the div component have a state? I don't get it. Is the forwardRef doing some magic and creating a state for the div element?

Why then if I pass the ref to the Button component it still gives the warning?

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

If I pass the antd Button directly as a child, it works. But this is because I suppose that the antd button has a state hence it can have refs.

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

解决方案

As the warning state you cannot assign refs to functional component without the usage the forwardRef

In order to have access to refs of any component, its required that a instance of the component is created and an instance is only created for class components, while functional components are invoked or called

From v16.8.0 onwards React introduced an API called useRef which allows you to create refs within functional components too which can be used on HTML nodes, class components or Functional components wrapped with forwardRef

To achieve the same behavior that is available in class components with ref, you can use forwardRef with useImperativeHandle hook to expose certain functions or states within the functional component to parent

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

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

  )
}

这篇关于理解:警告:不能给函数组件提供引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆