Build Custom Hooks

Build Custom Hooks

短篇 React 學習筆記。

What is React Hooks?

They are functions that let us hooks into React state and lifecycle features from function components.

Hooks reduces the complexity of state management. Redux is great for state management, but there are many steps in the process. Rather, hooks can be seen as a singular step. (More on this in a later post~)

Why build our own custom hooks?

Building our own hooks lets us extract component logic into reusable functions.

Sometimes, when we want to share logic between 2 JavaScript functions, we extract it to a third function.

Since hooks and components are JS function, we can extract them as well.

Building Custom Hooks

A custom Hook is a JavaScript function whose name starts with “use” and that may call other Hooks.

Say we want to to see if our friends are online. But we also want to build a contact list that shows us who is online.

So we can extract hook logic, and apply the hook into where the application needs the “friend status” logic.

Here’s our custom hook that shows if a friend is online:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

Now, say we want both Friend Status and Contact List to have the “friend status” logic.

That would be…

1
2
3
4
5
6
7
8
function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

and contact list…

1
2
3
4
5
6
7
8
9
function ContactListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

Keep in Mind…

  • We must use the prefix “use” in front of our hooks, so it doesn’t get confusing.
  • The states grabbed by hooks are completely isolated from one another. This means they don’t share the same state.
  • Each call to a Hook gets isolated state.