React Hooks, introduced in React 16.8, allow you to use state and other React features without writing a class. Hooks provide a more direct API to React concepts you already know: props, state, context, refs, and lifecycle. Here’s a guide to understanding all the built-in hooks in React.

1. useState

The useState hook allows you to add state to your functional components.

import { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

2. useEffect

The useEffect hook lets you perform side effects in function components, such as data fetching, subscriptions, or manually changing the DOM.

import { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

3. useContext

The useContext hook lets you subscribe to React context without introducing nesting.

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme.background, color: theme.foreground }}>I'm styled by theme context!</button>;
}

4. useReducer

The useReducer hook is an alternative to useState that’s preferable for complex state logic that involves multiple sub-values or when the next state depends on the previous one.

import { useReducer } from 'react';

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, {count: 0});

  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </>
  );
}

5. useCallback

The useCallback hook returns a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.

import { useCallback } from 'react';

function Example({ someProp }) {
  const memoizedCallback = useCallback(() => {
    doSomething(someProp);
  }, [someProp]);  // Only recreates the callback if `someProp` changes
}

6. useMemo

The useMemo hook returns a memoized value, only re-computing the memoized value when one of the dependencies has changed.

import { useMemo } from 'react';

function Example({ a, b }) {
  const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);  // Only re-runs the

 expensive function if `a` or `b` changes
}

7. useRef

The useRef hook is useful for accessing DOM nodes or keeping any mutable value around, similar to how you’d use instance fields in classes.

import { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

8. useImperativeHandle

The useImperativeHandle hook customizes the instance value that is exposed to parent components when using ref.

import { useImperativeHandle, useRef, forwardRef } from 'react';

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}

FancyInput = forwardRef(FancyInput);

9. useLayoutEffect

The useLayoutEffect hook is identical to useEffect but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.

import { useLayoutEffect } from 'react';

useLayoutEffect(() => {
  // Your code here. Similar to componentDidMount and componentDidUpdate. 
});

10. useDebugValue

The useDebugValue hook can be used to display a label for custom hooks in React DevTools.

import { useDebugValue } from 'react';

function useFriendStatus(friendID) {
  const isOnline = // Some logic...

  useDebugValue(isOnline ? 'Online' : 'Offline');

  return isOnline;
}

React Hooks are a powerful addition to React, giving you the tools to write your components in a simpler and more intuitive way, without sacrificing any of the power or flexibility of React. Remember, Hooks are completely opt-in and 100% backwards-compatible. You can use Hooks in all your new components, while keeping your old class-based components as they are.