15 Custom Hooks to Make your React Component Lightweight

15 Custom Hooks to Make your React Component Lightweight

Here are the 15 custom hooks to make your React component lightweight

Jul 12, 2021Β·

5 min read

React hooks is the trending word in the React community. I hope every React developer knows what hooks are. In simple words, hooks give the advantage to use lifecycle methods in functional components and also encourages us to write functional components.

Let’s dive into custom hooks! Custom hooks let you extract component logic into a reusable function, which increases component splitting and reliability. Here we will see 15 react-use package custom hooks that make our component lightweight.

1. useIdle

The useIdle hook tracks if the user on the page is idle. You can pass two params - one is time to consider idle and initialState, which allows the setting user is idle initially.

import {useIdle} from 'react-use';

const Demo = () => {
   const isIdle = useIdle(3e3);

return (
    <div>
      <div>User is idle: {isIdle ? 'Yes 😴' : 'Nope'}</div>
    </div>
  );
};

2. useInterval

This hook to use for interval-related functionalities. Which handles clearInterval on component unmount automatically. It also allows pausing the interval by setting the delay to null.

import * as React from 'react';
import {useInterval} from 'react-use';

const Demo = () => {
  const [count, setCount] = React.useState(0);
  const [delay, setDelay] = React.useState(1000);
  const [isRunning, toggleIsRunning] = useBoolean(true);

useInterval(
    () => {
      setCount(count + 1);
    },
    isRunning ? delay : null
  );

return (
    <div>
      <div>
        delay: <input value={delay} onChange={event => setDelay(Number(event.target.value))} />
      </div>
      <h1>count: {count}</h1>
      <div>
        <button onClick={toggleIsRunning}>{isRunning ? 'stop' : 'start'}</button>
      </div>
    </div>
  );
};

3. useScroll

This hook is used to listen to the scroll event of the element and rerenders on scrolling. No required to add the JavaScript event listeners manually.

import {useScroll} from 'react-use';

const Demo = () => {
  const scrollRef = React.useRef(null);
  const {x, y} = useScroll(scrollRef);
return (
    <div ref={scrollRef}>
      <div>x: {x}</div>
      <div>y: {y}</div>
    </div>
  );
};

4. useToggle

This hook is used to toggle between two states like TRUE, FALSE. This approach reduces the manual logic.

import {useToggle} from 'react-use';

const Demo = () => {
  const [on, toggle] = useToggle(true);
return (
    <div>
      <div>{on ? 'ON' : 'OFF'}</div>
      <button onClick={toggle}>Toggle</button>
      <button onClick={() => toggle(true)}>set ON</button>
      <button onClick={() => toggle(false)}>set OFF</button>
    </div>
  );
};

5. useTitle

This hook is used to set the page title.

import {useTitle} from 'react-use';

const Demo = () => {
  useTitle('Hello world!');
return null;
};

6. usePrevious

This hook is used to get the previous state. We might not require to write custom logic to get the previous state.

import {usePrevious} from 'react-use';

const Demo = () => {
  const [count, setCount] = React.useState(0);
  const prevCount = usePrevious(count);
return (
    <p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
      <p>
        Now: {count}, before: {prevCount}
      </p>
    </p>
  );
};

7. useSetState

This hook is used to merge objects into their current state, similar to the this.setState in the class component. If you are using multiple states, it can be brought down to a single object state using useSetState

import {useSetState} from 'react-use';

const Demo = () => {
  const [state, setState] = useSetState({});
return (
    <div>
      <pre>{JSON.stringify(state, null, 2)}</pre>
      <button onClick={() => setState({hello: 'world'})}>hello</button>
      <button onClick={() => setState({foo: 'bar'})}>foo</button>
      <button 
        onClick={() => {
          setState((prevState) => ({
            count: (prevState.count || 0) + 1,
          }))
        }}
      >
        count
      </button>
    </div>
  );
};

8. useCookie

This hook is used to return the current value of a cookie, a callback to update the cookie and a callback to delete the cookie.

import { useCookie } from "react-use";

const Demo = () => {
  const [value, updateCookie, deleteCookie] = useCookie("my-cookie");
  const [counter, setCounter] = useState(1);

useEffect(() => {
    deleteCookie();
  }, []);

const updateCookieHandler = () => {
    updateCookie(`my-awesome-cookie-${counter}`);
    setCounter(c => c + 1);
  };

return (
    <div>
      <p>Value: {value}</p>
      <button onClick={updateCookieHandler}>Update Cookie</button>
      <br />
      <button onClick={deleteCookie}>Delete Cookie</button>
    </div>
  );
};

9. usePermission

This hook is used to get the permission status of the browser API. Pass the API name to get the permission status.

import {usePermission} from 'react-use';

const Demo = () => {
  const state = usePermission({ name: 'microphone' });
return (
    <pre>
      {JSON.stringify(state, null, 2)}
    </pre>
  );
};

10. useDebounce

This hook is used to delay the event until the wait time is completed. In the blew code the setState is performed after the wait time is completed.

const Demo = () => {
  const [state, setState] = React.useState('Typing stopped');
  const [val, setVal] = React.useState('');
  const [debouncedValue, setDebouncedValue] = React.useState('');

const [, cancel] = useDebounce(
    () => {
      setState('Typing stopped');
      setDebouncedValue(val);
    },
    2000,
    [val]
  );

return (
    <div>
      <input
        type="text"
        value={val}
        placeholder="Debounced input"
        onChange={({ currentTarget }) => {
          setState('Waiting for typing to stop...');
          setVal(currentTarget.value);
        }}
      />
      <div>{state}</div>
      <div>
        Debounced value: {debouncedValue}
        <button onClick={cancel}>Cancel debounce</button>
      </div>
    </div>
  );
};

11. useGeolocation

This hook is used to get the user geolocation. useGeolocation returns latitude, longitude, altitude, and more info.

import {useGeolocation} from 'react-use';

const Demo = () => {
  const state = useGeolocation();
return (
    <pre>
      {JSON.stringify(state, null, 2)}
    </pre>
  );
};

12. useNetworkState

This hook is used to get the network status of the browser. useNetworkState can be used the show the connection status to the user.

import {useNetworkState} from 'react-use';

const Demo = () => {
  const state = useNetworkState();
return (
    <pre>
      {JSON.stringify(state, null, 2)}
    </pre>
  );
};

13. useCopyToClipboard

useCopyToClipboard hook is used to copy the text to the clipboard.

const Demo = () => {
  const [text, setText] = React.useState('');
  const [state, copyToClipboard] = useCopyToClipboard();

  return (
    <div>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button type="button" onClick={() => copyToClipboard(text)}>copy text</button>
      {state.error
        ? <p>Unable to copy value: {state.error.message}</p>
        : state.value && <p>Copied {state.value}</p>}
    </div>
  )
}

14. useFavicon

The useFavicon hook is used to set the favicon of the page.

import {useFavicon} from 'react-use';

const Demo = () => {
  useFavicon('https://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico');
return null;
};

15. useError

useError hook is used to dispatch errors.

import { useError } from 'react-use';

const Demo = () => {
  const dispatchError = useError();

const clickHandler = () => {
    dispatchError(new Error('Some error!'));
  };

return <button onClick={clickHandler}>Click me to throw</button>;
};

// In parent app
const App = () => (
  <ErrorBoundary>
    <Demo />
  </ErrorBoundary>
);

Conclusion

There are some more custom hooks in the react-use package, I hope you have found this useful. Thank you for reading.

Need to learn more? Feel free to connect on Twitter.

Did you find this article valuable?

Support Nilanth by becoming a sponsor. Any amount is appreciated!

Β