Using useOutletContext() Hook (ReactJS)

Using useOutletContext() Hook (ReactJS)

The React Router Dom UseOutletContext hook is a new feature introduced in version 6.1.01. It allows you to access the context value that is passed by the component to the child routes. This is useful when you want to share some state or other value between the parent and child routes.

An example of how to use the UseOutletContext hook is as follows:

// The parent component define the context!
function Parent() {
  const [count, setCount] = React.useState(0);
  return <Outlet context={[count, setCount]} />;
}

// The childen component access the context
import { useOutletContext } from "react-router-dom";
function Child() {
  const [count, setCount] = useOutletContext();
  const increment = () => setCount((c) => c + 1);
  return <button onClick={increment}>{count}</button>;
}

In this example, the parent component passes an array with the state and update function of the counter to the component, which renders the child component. The child component uses the UseOutletContext hook to get the value of the context and increment the counter when the button is clicked1.

If you are using TypeScript, it is recommended that the parent component provide a custom hook to access the context value. This makes it easier for consumers to get proper typing, control consumers, and know who is consuming the value of context. Here's a more realistic example:

// The parent component define and export the hook
import * as React from "react";
import type { User } from "./types";
import { Outlet, useOutletContext } from "react-router-dom";

type ContextType = {
  user: User | null;
};

export default function Dashboard() {
  const [user, setUser] = React.useState<User | null>(null);
  return (
    <div>
      <h1>Dashboard</h1>
      <Outlet context={{ user }} />
    </div>
  );
}

export function useUser() {
  return useOutletContext<ContextType>();
}

// The children component use the hook
import { useUser } from "../dashboard";
export default function DashboardMessages() {
  const { user } = useUser();
  return (
    <div>
      <h2>Messages</h2>
      <p>Hello, {user.name}!</p>
    </div>
  );
}

In this example, the parent component defines a type for the context and exports a hook named useUser that uses the UseOutletContext hook with that type. The child component imports the useUser hook and gets the user from the context.

What's the difference between this hook and useContext?

The difference between the UseOutletContext hook and the useContext is that the former is specific to accessing the context that is passed by the component of the React Router Dom, while the latter is a general React hook for accessing any user-created context.

The UseOutletContext is a convenient way to share some value between parent and child routes without having to create a context provider of your own. However, it only works on the immediate child component, so if you have nested routes, you'll have to go through the context again. In addition, it can only access the context of the and not from other context providers that you may have in your application.

useContext is a more generic hook that allows you to access any user-created context with React's createContext function. It can be used on any component that is inside a context provider, no matter the nesting level. It can also access multiple different contexts if you use multiple context providers in your application.

Therefore, the UseOutletContext is a more specific and limited way to access the context than the useContext. You can choose which one to use depending on your need and preference.