useRef
The useRef
hooks creates and manages mutable containers inside your React component.
Usage
React.useRef
returns a mutable ref object whose .current
record field is initialized to the passed argument (initialValue
). The returned object will persist for the full lifetime of the component.
Essentially, a React.ref
is like a "box" that can hold a mutable value in its .current
record field.
You might be familiar with refs primarily as a way to access the DOM. If you pass a ref object to React with <div ref={ReactDOM.Ref.domRef(myRef)} />
, React will set its .current
property to the corresponding DOM node whenever that node changes.
However, useRef()
is useful for more than the ref attribute. It's handy for keeping any mutable value around similar to how you’d use instance fields in classes.
This works because useRef()
creates a plain JavaScript object. The only difference between useRef()
and creating a {current: ...}
object yourself is that useRef will give you the same ref object on every render.
Keep in mind that useRef
doesn’t notify you when its content changes. Mutating the .current
record field doesn’t cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a callback ref instead.
More infos on direct DOM manipulation can be found in the Refs and the DOM section.
Examples
Managing Focus for a Text Input
// TextInputWithFocusButton.res
@send external focus: Dom.element => unit = "focus"
@react.component
let make = () => {
let inputEl = React.useRef(Js.Nullable.null)
let onClick = _ => {
inputEl.current
->Js.Nullable.toOption
->Belt.Option.forEach(input => input->focus)
}
<>
<input ref={ReactDOM.Ref.domRef(inputEl)} type_="text" />
<button onClick> {React.string("Focus the input")} </button>
</>
}
Using a Callback Ref
Reusing the example from our Refs and the DOM section:
// CustomTextInput.res
@send external focus: Dom.element => unit = "focus"
@react.component
let make = () => {
let textInput = React.useRef(Js.Nullable.null)
let setTextInputRef = element => {
textInput.current = element;
}
let focusTextInput = _ => {
textInput.current
->Js.Nullable.toOption
->Belt.Option.forEach(input => input->focus)
}
<div>
<input type_="text" ref={ReactDOM.Ref.callbackDomRef(setTextInputRef)} />
<input
type_="button" value="Focus the text input" onClick={focusTextInput}
/>
</div>
}