React.useRef and React.createRef: The Difference
The similarities and differences of React.useRef and React.createRef.

React.createRef and React.useRef
Both React APIs are used to create a mutable object. The mutable object’s properties can be changed at will without affecting the Component’s state.
The object has a current
property, this property is where the value is stored and referenced.
These APIs create these mutable objects which can be called refs
. They hold a reference to any value we want.
React.createRef are used in class components to create refs.
Tip: Thanks to React Hooks it is now easier than ever to create reusable components with clear an explicit API. Use tools like Bit to “harvest” React components from any codebase and share them on bit.dev. It’s a great way for you and your team to maximize code reuse, speed up development and build a scalable and maintainable codebase.

class App extends React.Component {
componentDidMount() {
this.divRef = React.createRef()
}
render() {
return (
<div>
<div id="divR" ref={this.divRef}>App, here</div>
</div>
)
}
}
Here, a ref is created in divRef. We assign it as a value to the ref
attribute in the div#divR
element in the render method.
This will create a DOM instance of the div#divR
and assign it to divRef
. The DOM instance can be referenced from the current
property in divRef.
divRef.current instanceof HTMLDivElementtrue
In function components, we use React.useRef:
function App { const divRef = React.useRef() return (
<div>
<div id="divR" ref={divRef}>App, here</div>
</div>
)
}
The same effect as in the React component version. useRef will create a ref in divRef. Using the ref attribute in div#divR, we will assign the DOM instance of div#divR to divRef. To get the DOM instance from divRef, we reference its current property.
createRef and useRef can be used to store any value, not only DOM instances via ref
.
function App { const divRef = React.useRef()
const valueRef = React.useRef(90) return (
<div>
Value: {valueRef.current}
<div id="divR" ref={divRef}>App, here</div>
<button onClick={()=> valueRef.current = 88}>Incr</button>
</div>
)
}
valueRef is a ref that holds value 90 in its current property. We displayed the valueRef value in the render method by referencing current in the JSX braces. When the component renders we will see 90.
Changing the values of the refs won’t re-render the component. See the Incr button, when clicked it would change the valueRef value to 88, this won’t re-render the component. So we will still see 90 (the old value of the valueRef) in the DOM. That means, we need to trigger re-render in the component to see the current value of valueRef.
function App { const divRef = React.useRef()
const valueRef = React.useRef(90)
const [,setDummyState] = useState() return (
<div>
Value: {valueRef.current}
<div id="divR" ref={divRef}>App, here</div>
<button onClick={()=> (valueRef.current = 88, setDummyState({}))}>Incr</button>
</div>
)
}
We created a dummy state and a summy function to trigger re-render in the component. Now, clicking on the Incr
will re-render the component and we will see the updated value in valueRef
reflect in the DOM.
We have seen their uses, and they are the same.
We can only use createRef in class components. We can only use useRef in function components.
Using createRef in function components will throw no error, but it will result in inconsistencies.
For example, if we change the above function App to use createRef:
function App { const valueRef = React.createRef()
const [,setDummyState] = useState() return (
<div>
Value: {valueRef.current}
<button onClick={()=> (valueRef.current = 88, setDummyState({}))}>Incr</button>
</div>
)
}
No matter, how many times we click the Incr button our value will always be null. The valueRef is updated to 88 and the function App is re-rendered.
This is because function components are functions, and them re-rendering or rendering is still running them like normal functions.
App()let props = {
name: "nnamdi",
age: 90
}App(props)
The thing is that function components returns JSX that will be rendered by React in the browser DOM.
Now, when the function App is re-rendered, the function is run and this will re-initialize and re-create all expressions and statements in its body. So the createRef will be run every time and the value will always be null. See createRef source:
That’s why useRef hook was created to maintain the ref current value throughout the function component’s lifetime, re-running the function on re-render won’t re-create the ref value.
createRef works well in class components because the re-rendering the components only calls the render method, shouldComponent, and componentDidMount methods.
// mounting
const appInstance = new App(props, context)
// constructor is called and ref is created
appInstance.componentWillMount()
appInstance.componentDidMount()// re-rendering
if(appInstance.shouldComponentUpdate())
appInstance.componentWillMount()
appInstance.componentDidMount()
It doesn’t re-instantiate the class, so the ref value is consistent throughout the class components lifetime.
To make sure your ref value is maintained throughout your component’s lifetime create them in the constructor method. Creating in any of the methods that are run on re-render will re-create them every time.
Conclusion
We now have our answer.
If you have any questions regarding this or anything I should add, correct or remove, feel free to comment, email or DM me.
Thanks !!!