There is a functional ponent implemented with getElementById and it needs to be updated to use useRef hook.
Original code:
import React, { useState, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
const MyComponent: React.FunctionComponent<MyComponentProps> = ({
myDefaultElement = 'default-element',
}) => {
const [elementOutlet, setElementOutlet] = useState<HTMLOListElement>();
useEffect(() => {
const refElement = document.getElementById(myDefaultElement) as HTMLOListElement;
if (refElement) {
setElementOutlet(refElement);
}
}, [myDefaultElement]);
return createPortal(
<li>
// something
</li>,
elementOutlet
);
};
the above code works fine, the only change that I made was the first line inside useEffect.
From:
const refElement = document.getElementById(myDefaultElement) as HTMLOListElement;
To:
const refElement = useRef(myDefaultElement) as HTMLOListElement;
When hover the new line it says:
React Hook "useRef" cannot be called inside a callback. React Hooks must be called in a React function ponent or a custom React Hook function
Is there a way to make ref work fine inside useEffect?
There is a functional ponent implemented with getElementById and it needs to be updated to use useRef hook.
Original code:
import React, { useState, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
const MyComponent: React.FunctionComponent<MyComponentProps> = ({
myDefaultElement = 'default-element',
}) => {
const [elementOutlet, setElementOutlet] = useState<HTMLOListElement>();
useEffect(() => {
const refElement = document.getElementById(myDefaultElement) as HTMLOListElement;
if (refElement) {
setElementOutlet(refElement);
}
}, [myDefaultElement]);
return createPortal(
<li>
// something
</li>,
elementOutlet
);
};
the above code works fine, the only change that I made was the first line inside useEffect.
From:
const refElement = document.getElementById(myDefaultElement) as HTMLOListElement;
To:
const refElement = useRef(myDefaultElement) as HTMLOListElement;
When hover the new line it says:
React Hook "useRef" cannot be called inside a callback. React Hooks must be called in a React function ponent or a custom React Hook function
Is there a way to make ref work fine inside useEffect?
Share Improve this question edited Jul 25, 2022 at 7:24 Leo Messi asked Nov 17, 2021 at 13:14 Leo MessiLeo Messi 6,23622 gold badges80 silver badges155 bronze badges1 Answer
Reset to default 4You can't call useRef
inside an effect, check the rule of hooks. Try something like this
const Component = () =>{
const node = useRef(null)
useEffect(() =>{
// current will never be null here, since this effect will
// only run after the first mount and therefore after refs
// appending
setElementOutlet(node.current)
},[])
return <div ref={node} />
}
Refs already have an stable signature ensured by react's life cycle, so you don't have to declare it as a dependency inside your effect.
Judging by your example you're only receiving an id
as props not the node itself. You have two options:
- Continue to receive the element id and calling
getElementById
(there is nothing wrong with that) and then append the mounted node inside a ref
const Component = ({ id }) =>{
const node = useRef(document.getElementById(id))
useEffect(() =>{
const el = document.getElementById(id)
if(el) node.current = el
},[id])
}
- Receive the entire ref as props
const ParentComponent = () =>{
const node = useRef(null)
return(
<>
<Component childRef={node} />
<div ref={node} />
</>
)
}
const Component = ({ childRef }) =>{
...
}
Greetings fellow olister.