React
Hooks

Hooks

What are React Hooks?

Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes. (We don’t recommend rewriting your existing components overnight but you can start using Hooks in the new ones if you’d like.)

Rules of Hooks

Only Call Hooks at the Top Level

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls. (If you’re curious, we’ll explain this in depth below.)

Only Call Hooks from React Functions

Don’t call Hooks from regular JavaScript functions. Instead, you can:

Call Hooks from React function components.

Call Hooks from custom Hooks

By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.

Built In Hooks

useCallback - https://react.dev/reference/react/useCallback (opens in a new tab)

useContext - https://react.dev/reference/react/useContext (opens in a new tab)

useDebugValue - https://react.dev/reference/react/useDebugValue (opens in a new tab)

useDeferredValue - https://react.dev/reference/react/useDeferredValue (opens in a new tab)

useEffect - https://react.dev/reference/react/useEffect (opens in a new tab)

useId - https://react.dev/reference/react/useId (opens in a new tab)

useImperativeHandle - https://react.dev/reference/react/useImperativeHandle (opens in a new tab)

useInsertionEffect - https://react.dev/reference/react/useInsertionEffect (opens in a new tab)

useLayoutEffect - https://react.dev/reference/react/useLayoutEffect (opens in a new tab)

useMemo - https://react.dev/reference/react/useMemo (opens in a new tab)

useOptimistic - https://react.dev/reference/react/useOptimistic (opens in a new tab)

useReducer - https://react.dev/reference/react/useReducer (opens in a new tab)

useRef - https://react.dev/reference/react/useRef (opens in a new tab)

useState - https://react.dev/reference/react/useState (opens in a new tab)

useSyncExternalStore - https://react.dev/reference/react/useSyncExternalStore (opens in a new tab)

useTransition - https://react.dev/reference/react/useTransition (opens in a new tab)

Custom Hooks

Here is an example of a custom hook used to detect and track the state of device orientation found in the repo below.

Awesome React Hooks (opens in a new tab)

useOrientation

useOrientation.js
 
import { useEffect, useState } from 'react';
//use to detect Window | Document | HTMLElement | EventTarget types
import { off, on } from './misc/util';
 
 
const defaultState = {
  angle: 0,
  type: 'landscape-primary',
};
 
const useOrientation = (initialState = defaultState) => {
  const [state, setState] = useState(initialState);
 
  useEffect(() => {
    const screen = window.screen;
    let mounted = true;
 
    const onChange = () => {
      if (mounted) {
        const { orientation } = screen as any;
 
        if (orientation) {
          const { angle, type } = orientation;
          setState({ angle, type });
        } else if (window.orientation !== undefined) {
          setState({
            angle: typeof window.orientation === 'number' ? window.orientation : 0,
            type: '',
          });
        } else {
          setState(initialState);
        }
      }
    };
 
    on(window, 'orientationchange', onChange);
    onChange();
 
    return () => {
      mounted = false;
      off(window, 'orientationchange', onChange);
    };
  }, []);
 
  return state;
};
 
export default useOrientation
 
CoolPage.jsx
import useOrientation from "../hooks/useOrientation";
 
export default function CoolPage() {
  const orientation = useOrientation();
 
  return (
    <div>
      <pre>
        <code>{JSON.stringify(orientation)}</code>
      </pre>
    </div>
  );
}

Output

Switch to mobile in DevTools to see the changes.

{"angle":0,"type":"landscape-primary"}

It wasn't always like this!

In the early days of React, stateful components were class based and functional components were functions.

You can view an example of an app converted from the old style to the new style demoed for a class when hooks were introduced here:

Class based app: https://github.com/jhadev/pupster-example (opens in a new tab)

Function based app with hooks: https://github.com/jhadev/pupster-alts (opens in a new tab)