Here I have a parent component with a button and a child component with a function to show an alert.
but I was getting this error,
Function components cannot be given refs. Attempts to access this ref will fail.
code:
import { useRef } from "react"
const ChildComp = () => {
function showAlert() {
alert("Hello from Child Component")
}
return <div></div>
}
function App() {
const childCompRef = useRef()
return (
<div>
<button>Click Me</button>
<ChildComp ref={childCompRef} />
</div>
)
}
export default App
What's the issue?
CodePudding user response:
import React, { useRef } from "react";
const ChildComp = React.forwardRef((props, ref) => {
function showAlert() {
alert("Hello from Child Component");
}
return <div ref={ref}></div>;
});
function App() {
const childCompRef = useRef();
return (
<div>
<button>Click Me</button>
<ChildComp ref={childCompRef} />
</div>
);
}
export default App;
Here you have to use forwardRef in child component if you want to pass refs.
CodePudding user response:
import React, { useRef } from "react";
const ChildComp = React.forwardRef((props, ref) => {
function showAlert() {
alert("Hello from Child Component");
}
return <button ref={ref} onClick={(e)=>showAlert()}>Click Me</button>;
});
function App() {
const childCompRef = useRef();
return (
<div>
<ChildComp ref={childCompRef} />
</div>
);
}
export default App;
CodePudding user response:
When we enclose the child component with forwardRef
, it receives a second parameter apart from props
, which is the ref
passed from the parent component
.
Now with the help of this ref, we can specify which functions can be accessed by the parent component
. This can be done using useImperativeHandle hook
, as shown below:
import { forwardRef, useRef, useImperativeHandle } from "react"
const ChildComp = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
showAlert() {
alert("Hello from Child Component")
},
}))
return <div></div>
})
function App() {
const childCompRef = useRef()
return (
<div>
<button onClick={() => childCompRef.current.showAlert()}>Click Me</button>
<ChildComp ref={childCompRef} />
</div>
)
}
export default App
I found this helpful as well, StackOverflow