What Should You Use Instead of QuerySelector in React

Ferenc Almasi β€’ 2022 September 14 β€’ πŸ“– 3 min read

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:

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>
    )
}
Copied to clipboard!

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.

<footer>Footer</footer>
Logging ref.current to the console
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
JavaScript Course

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:

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>
    )
}
Copied to clipboard!

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.

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 ...
}
Copied to clipboard!
JavaScript Course Dashboard

Tired of looking for tutorials?

You are not alone. Webtips has more than 400 tutorials which would take roughly 75 hours to read.

Check out our interactive course to master JavaScript in 5 hours.

Learn More

πŸ“š Get access to exclusive content

Want to get access to exclusive content? Support webtips with the price of a coffee to get access to tips, checklists, cheatsheets, and much more. β˜•

Get access Support us
Read more on
πŸŽ‰ Thank you for subscribing to our newsletter. x