avatarXiuer Old

Summarize

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:

If you enjoyed this article, consider trying out the AI service I recommend. It provides the same performance and functions to ChatGPT Plus(GPT-4) but more cost-effective, at just $6/month (Special offer for $1/month). Click here to try ZAI.chat.

JavaScript
React
React Hook
Reactjs
Web Development
Recommended from ReadMedium