7 Uncommonly Used But Very Useful Hooks In React
Today I will introduce a few React hooks
that are not commonly used, but can bring useful help to your work.
useSyncExternalStore
Monitor external data changes
The external data source needs to provide a subscription function, and this function needs to return a method to cancel the subscription.
import React from 'react';
import { store } from './store.js'
export const App () {
const data = useSyncExternalStore(store.subscribe, store.getData)
return <>
<button onClick={store.add}>add+</button>
{data}
</>
}
// store.js
let conut = 0;
let listeners = [];
export const store = {
add () {
count ++;
},
subscribe(listener) {
listeners = [...listeners, listener];
return () => {
listeners = listeners.filter(l => l !== listener);
};
},
geetDate () {
return count;
}
}
useId
Generate a globally unique ID, give up Math.random()
now
import { useId } from 'react';
function App() {
const uuid = useId();
return (
<>{uuid}</>
);
}
useLayoutEffect
Triggered before layout update
import { useState, useRef, useLayoutEffect } from 'react';
function Tooltip() {
const ref = useRef(null);
const [tooltipHeight, setTooltipHeight] = useState(0);
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipHeight(height);
}, []);
return <></>
}
useDeferredValue
UI delayed update, no need to write anti-shake function by hand
import SearchResults from './SearchResults.js';
export default function App() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
return (
<>
<label>
Search albums:
<input value={query} onChange={e => setQuery(e.target.value)} />
</label>
<Suspense fallback={<h2>Loading...</h2>}>
<SearchResults query={deferredQuery} />
</Suspense>
</>
);
}
useReducer
Customize a lightweight redux
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
useRef
Define a reference to a value
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
useImperativeHandle
Customize ref
the handle exposed by.
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} {..props} />;
}
In Plain English
Thank you for being a part of our community! Before you go:
- Be sure to clap and follow the writer! 👏
- You can find even more content at PlainEnglish.io 🚀
- Sign up for our free weekly newsletter. 🗞️
- Follow us: Twitter(X), LinkedIn, YouTube, Discord.
- Check out our other platforms: Stackademic, CoFeed, Venture.