Skip to content

Refs

Because the state of your application lives in the DOM, you will often want to keep references to specific DOM elements so you can read and modify them. This is what refs are for. They work similarly to React; the DOM element is assigned to the .current attribute of the ref.

function Counter() {
const countSpanRef = {};
function handleClick() {
const prevValue = parseInt(countSpanRef.current.textContent);
countSpanRef.current.textContent = `${prevValue + 1}`;
}
return (
<>
<div>
<button onClick={handleClick}>Click me</button>
</div>
<div>
Count: <span ref={countSpanRef}>0</span>
</div>
</>
);
}
document.body.append(<Counter />);

When a ref prop is encountered in JSX, the produced DOM element is assigned to the current property of the ref.

Since you will use refs a lot, there is a helper to create them:

const [ref1, ref2, ref3] = useRefs();

This is roughly equivalent to:

const [ref1, ref2, ref3] = [{}, {}, {}];

(refs are simply empty objects; useRefs returns an endless list of them)

useRefProxy creates refs lazily using Proxy objects. Instead of declaring individual refs, you get an object that creates refs on-demand when you access properties:

function App() {
const refs = useRefProxy();
return (
<>
<input ref={refs.username} />
<input ref={refs.password} />
<button ref={refs.submitBtn}>Submit</button>
</>
);
}

This is equivalent to const refs = { username: {}, password: {}, submitBtn: {} } but more concise when you have many refs.