Skip to main content

Command Palette

Search for a command to run...

Revisiting React Hooks

Published
•3 min read•View as Markdown
Revisiting React Hooks

React hooks help us manage state, optimize performance, and handle side effects without writing class components. Here’s an attempt to breakdown some key hooks and how they are used in easy-to-understand manner.

1. useState

State is just data that changes over time or gets re-rendered. useState is the hook used to manage it. It returns two things: the state variable (this is the actual data you’re trying to display) and the update function (this updates the state and triggers a re-render). Typically, it looks like:

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

count starts at 0. setCount is the function used to update it. Every time setCount is called, count updates and React re-renders the component.

2. useRef

Similar to state but doesn’t trigger re-renders. useRef holds a value that persists between renders but updates instantly without causing the component to re-render. It’s useful for keeping track of mutable values, and it’s often used for interacting with DOM elements:

const inputRef = useRef(null);
<input ref={inputRef} />;

Here, inputRef is assigned to a DOM element, allowing direct access to it without causing a re-render when modified. This is useful for managing focus, measuring element dimensions, or storing previous values.

3. useMemo

Sometimes, recomputing values every render can slow things down. useMemo stores the result of a function and only recalculates when dependencies change.

const filteredList = useMemo(() => data.filter(item => item.active), [data]);

Instead of filtering data on every render, useMemo makes sure it only recalculates when data changes. This prevents unnecessary processing and improves performance in applications with large datasets.

4. useCallback

Similar to useMemo, but for functions. Instead of recalculating a value, it memorizes a function so it doesn’t get re-created on every render. Useful for optimizing child components that rely on functions as props:

const handleClick = useCallback(() => console.log("Clicked!"), []);

Normally, a function would be recreated every time a component re-renders. useCallback ensures that handleClick keeps the same reference across renders unless its dependencies change. This helps prevent unnecessary re-renders in child components that rely on it.

5. useEffect

This is used for side effects, like fetching data or updating the DOM. Side effects usually depend on state changes. The dependency array tells React when to run the effect. If you add a cleanup function, React will run it before the component unmounts or before the effect runs again:

useEffect(() => {
  console.log("Effect ran");
  return () => console.log("Cleanup before re-run");
}, [state]);

Here, the effect runs every time state changes. The cleanup function runs before the next execution, ensuring proper resource management, such as unsubscribing from APIs or clearing timeouts.

6. useContext

Passing props down multiple levels can be a hassle. useContext allows components to access shared data without prop drilling:

const theme = useContext(ThemeContext);

Instead of manually passing theme as a prop to every child component, useContext allows any component inside ThemeContext.Provider to access it directly. This makes state management easier, especially in larger applications.

For further study:

React documentation on Hooks
Cosden Solutions Youtube Playlist on React Hooks