Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hooks: Why is .current null for useRef Hook?

I have a simple example of a component:

function App() {   const observed = useRef(null);   console.log(observed.current);    return (     <div ref={observed} className="App">       <h1>Hello CodeSandbox</h1>       <h2>Start editing to see some magic happen!</h2>     </div>   ); }  const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

I would expect that observed.current would be of type element and current would not be empty but the div element with all its properties. My understanding would be:

  1. The ref is initialised with a value of null
  2. Null is overwritten by the ref

But as it turns out, .current remains empty. This is bad since I want to pass observed to a function that expects an argument of type Element.

https://codesandbox.io/embed/purple-forest-0460k

like image 662
Xen_mar Avatar asked Jun 11 '19 10:06

Xen_mar


People also ask

Why does useRef return null?

The "Object is possibly null" error is caused because the useRef() hook can be passed an initial value as an argument and we're passing it null as an initial value. The hook returns a mutable ref object whose . current property is initialized to the passed argument.

What is .current in useRef?

useRef() only returns one item. It returns an Object called current . When we initialize useRef we set the initial value: useRef(0) . It's like doing this: const count = {current: 0} . We can access the count by using count.

Why is useRef current undefined?

current property is initialized to the passed argument. We didn't pass an initial value to useRef so its current property is set to undefined . If we had passed null to the hook, its current property would be null if accessed immediately.

Does useEffect work with useRef?

If you want to respond to a React element's mounting on the DOM, you may be tempted to use useRef to get a reference to it and useEffect to respond to its mounts and unmounts. But it won't work.


1 Answers

Ref.current is null because the ref is not set till after the function returns and the content is rendered. The useEffect hook fires every time the value of contents of the array passed to it changes. By passing observed in the array and by passing a callback that logs observed to the console, the useEffect hook can be leveraged to accomplish your task.

  useEffect(() => {     console.log(observed.current);   }, [observed]); 

Edit: This only works on the first render as changes to a ref do not trigger re-renders. But the general statement about useEffect still holds. If you want to observe changes to a ref of a dom element, you can use a callback as ref.

  <div      ref={el => { console.log(el); observed.current = el; }} // or setState(el)     className="App"   > 

Code Sandbox

like image 76
Avin Kavish Avatar answered Sep 18 '22 17:09

Avin Kavish