What Should You Use Instead of QuerySelector in React

Ferenc Almasi β€’ 2022 September 14 β€’ Read time 3 min read
  • twitter
  • facebook
React

Instead of using document.querySelector in React, you should access DOM elements using the useRef hook, and grab the element using ref.current. Take a look at the following example:

Copied to clipboard! Playground
import { useRef } from "react"

export default function App() {
    const ref = useRef()

    console.log(ref.current)

    const scroll = () => {
        ref.current.scrollIntoView()
    }

    return (
        <div className="App">
            <button onClick={scroll}>Scroll to footer</button>
            <p>...</p>
            <footer ref={ref}>Footer</footer>
        </div>
    )
}

Here we are using useRef to scroll the footer into view. First, you will need to create a new ref using the useRef hook, and assign the reserved ref prop to the element that you want to access.

React will store the DOM element inside ref.current, which you can access anywhere in your component. Logging ref.current to the console will return the footer itself. On ref.current, we can call all functions we normally would on document.querySelector.

Copied to clipboard!
<footer>Footer</footer>
Logging ref.current to the console

How to Pass ref to Child Components in React

In case you need to pass a ref to a child component in React, you can use a feature called forwardRef. forwardRef wraps your component into a function so that references can be passed down to child components. In order to make your child accept a ref from a parent, import forwardRef from React, and wrap your component with the function:

Copied to clipboard! Playground
import { createRef, forwardRef } from 'react'

const Child = forwardRef((props, ref) => {
    return <span className="child" ref={ref}>Child component</span>
})

export default function App() {
    const ref = createRef()

    console.log(ref.current)

    return (
        <div className="app">
            <Child ref={ref} />
        </div>
    )
}

This function accepts the props as the first parameter and a ref as the second. Make sure you pass the ref to the correct DOM element. Now instead of using the useRef hook, we need to use createRef to create a reference, and pass it down to our child components. Now you should be able to access ref.current, just as you would with a useRef hook.


Using document.querySelector directly

In case you are dealing with a third-party library where you have no option passing around ref, you can use document.querySelector as a last resort. Make sure, however, that you call it inside a useEffect hook to ensure that your component is already mounted, before trying to access the element.

Copied to clipboard! Playground
import { useEffect } from 'react'

export default function App() {
    // ❌ This will return null as the element doesn't exists yet
    console.log(document.querySelector('footer'))
  
    // βœ”οΈ This will work
    useEffect(() => {
        console.log(document.querySelector('footer'))
    }, [])

    return ...
}
  • twitter
  • facebook
React
Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access 100+ interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Prepare for technical interviews
Become a Pro

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.