How I'm Using PocketBase with React Context

For several years now, I've been building my side projects with a PocketBase backend.

Here's the Context component (and custom hook) I'm using to manage authentication in a React (Vite) app:

import React from "react";
import PocketBase from "pocketbase";
import { useInterval } from "usehooks-ts";
import { jwtDecode } from "jwt-decode";
import ms from "ms";

const BASE_URL = import.meta.env.VITE_PB_URL;
const fiveMinutesInMs = ms("5 minutes");
const twoMinutesInMs = ms("2 minutes");

const PocketContext = React.createContext({});

export const PocketProvider = ({ children }) => {
  const pb = React.useMemo(() => new PocketBase(BASE_URL), []);
  pb.autoCancellation(false);

  const [token, setToken] = React.useState(pb.authStore.token);
  const [user, setUser] = React.useState(pb.authStore.record);

  React.useEffect(() => {
    return pb.authStore.onChange((token, record) => {
      setToken(token);
      setUser(record);
    });
  }, []);

  async function register(email, password) {
    try {
      // Create user
      const data = {
        email,
        password,
        passwordConfirm: password,
      };

      const newUser = await pb.collection("users").create(data);

      // Log them in
      await pb.collection("users").authWithPassword(email, password);

      return newUser;
    } catch (error) {
      console.error("Registration error:", error);
      throw error;
    }
  }

  async function login(email, password) {
    try {
      return await pb.collection("users").authWithPassword(email, password);
    } catch (error) {
      console.error("Login error:", error);
      // You might want to show this error to the user
      throw error; // Re-throw to handle in the UI
    }
  }

  function logout() {
    pb.authStore.clear();
    // No navigation here - we'll handle it in the component
  }

  async function refreshSession() {
    if (!pb.authStore.isValid) return;
    const decoded = jwtDecode(token);
    const tokenExpiration = decoded.exp;
    const expirationWithBuffer = (decoded.exp + fiveMinutesInMs) / 1000;
    if (tokenExpiration < expirationWithBuffer) {
      await pb.collection("users").authRefresh();
    }
  }

  useInterval(refreshSession, token ? twoMinutesInMs : null);

  return (
    <PocketContext.Provider
      value={{
        register,
        login,
        logout,
        user,
        token,
        pb,
      }}
    >
      {children}
    </PocketContext.Provider>
  );
};

export const usePocket = () => React.useContext(PocketContext);