DEV Community

Kyle Buntin
Kyle Buntin

Posted on • Updated on • Originally published at quickcomponent.com

CreateRef VS UseRef

React

A long time React user must have come across createRef and useRef refs to avoid the typical React dataflow and access a DOM element or a React component. Initially, these two provide similar functions, especially when looking closer at how each of them functions. Although, this is not the case. In order to eliminate the confusion between createRef and useRef, emphasis on the differences between these two will be given.

First, before going deep into their differences, it is important to know how and where refs can be used in React.

Specifically in React, Refs provides an escape invent to directly access React components or DOM elements in place of props and component state. This however, gives us the chance to modify the values that are associated with the React component or DOM elements without substituting its state. Moving forward, we’ll be going into the differences between CreateRef and UseRef.

The utmost difference between CreateRef and UseRef is that it is advisable to use CreateRef inside class components and UseRef inside function components. The question now is, can we use it the other way round? An example will be given below.

function TextInput () {
    const textInput = createRef()

    const focusOnInput = () => {
        textInput.current.focus()
    }

    return (
        <div>
            <input ref={textInput} type="text" />
            <button onClick={focusOnInput}>Focus on text input</button>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

In the example above, using CreateRef does not have any specific difference to using useRef. Both refs successfully achieves the required goal of focusing the input in this situation.

However, what if we decide to use CreateRef instead of useRef for a different situation inside the following ValueComponent function?

function ValueComponent () {
    const valueComponent = createRef(10)

    const changeValue = () => {
       valueComponent.current += 1
    }


    return (
        <div>
            <div ref={valueComponent}>Value: {valueComponent.current}</div>
            <button onClick={changeValue}>Change Value</button>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Here, we can still get away with using CreateRef inside function component. The question now is; What happens if we render the element after changing the value stored in ref?

function ValueComponent () {
    const valueComponent = React.createRef(10)
    const {state, setState} = React.useState()


    return (
        <div>
            <div ref={valueComponent}>Value: {valueComponent.current}</div>
            <button onClick={() => (valueComponent.current = 2, setState({}))}>Change Value</button>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Clicking on the button, we expect to see the value inside the div to change to 2 from the initial value of 10. In reality however, the value displayed is not 2 but 10. Why is this so?

Once a function component re-renders, it acts like a normal function and execute the full content in function logic. In this case, though the value of component current changes to 2 when we click the button, it changes again to 10 once the component re-renders. It is clear that the displayed value does not change as expected.

Furthermore, CreateRef works with class components in this structure because re-rendering a class component only calls the render() function of the component. Given the nature of function complements, it is safe to say we cannot use createRef with them in the same aspect. Alternatively, we have to make use of useRef.

UseRef however does not reboot its values every time a function component re-renders. As a substitute, it persists the value stored all through the lifetime of the component.

function ValueComponent () {
    const valueComponent = React.useRef(10)
    const {state, setState} = React.useState()


    return (
        <div>
            <div ref={valueComponent}>Value: {valueComponent.current}</div>
            <button onClick={() => (valueComponent.current = 2, setState({}))}>Change Value</button>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

When the button is clicked, the value changes to 2.

In summary, in the process of using React for fronted development, there are situations where we have to go from the typical dataflow to directly accessing the DOM elements and React components. We make use of createRef and useRef API’s for this reason.
Nevertheless, the two refs behave similarly most of the time, there is still a major difference between the two: createRef is required to be used inside Class components and useRef is required to be used inside function components. With this in mind, one can make use of React refs one program without needing to debate on which one to choose from henceforth.

If you are interested in learning React native, you can check out this cool mobile templates at Quick Component. These mobile templates are production ready and also good for learning purposes.
They include;
Dating app Whatsapp clone and more

Top comments (0)