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>
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.
Creating RefsRefs are created using React.createRef() and attached to React elements via the ref attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component.
To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.
FormInput is a class component so we can create a reference to it. However, we can use a ref inside a functional component like we did in this example using formInput . Finally, in the inputSelection() function, we access the reference to our component using the current attribute of the ref as before.
Don't be confused, first this it's not related to functional or class components issue means you can use ref for both, react 16+ has hook useRef
so you can used ref for functional components also,
Answer to your question, antd
Button
has their own ref so it's omitting the ref passed by parent component in you case Tooltip
that why your are not seeing any warning for that but when you used your own component that time you have to take of ref
passed by Tooltip
.
And, still you don't want to use React.forwordRef
then simply ignore it while passing props to your component. but then you don't get privileged some feature provided by antd
controlled components
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With