React Context API with TypeScript

Koushik RoyKoushik Roy
2 min read

Creating a Context and Provider

To start using the React Context API, we need to create a context using the createContext method:

The Provider component is responsible for wrapping the part of the component tree where we want to make the context data available. It accepts a value prop, which holds the data we want to share:

// src/context/UserContextProvider.tsx
import { ReactNode, createContext, useContext, useState } from "react";

// type definition for the user
type UserType = {
  username: string;
  password: string;
};

// type definition for UserContext
type UserContextType = {
  user: UserType | null;
  setUser: React.Dispatch<React.SetStateAction<UserType | null>>;
};

// type definition for UserContextProviderProps
type UserContextProviderProps = {
  children: ReactNode;
};

// creating a context
const UserContext = createContext<UserContextType | null>(null);

export default function UserContextProvider({
  children,
}: UserContextProviderProps) {
  const [user, setUser] = useState<UserType | null>(null);

  return (
    <UserContext.Provider
      value={{
        user,
        setUser,
      }}
    >
      {children}
    </UserContext.Provider>
  );
}

// custome hooks
export function useUserContext() {
  const context = useContext(UserContext);

  if (!context) {
    throw new Error("useUserContext must be used within a UserConextProvider");
  }
  return context;
}

Wrap the main element/app component with UserContextProvider

Wrap all the components that will be using the Provider or the main App component

// src/App.tsx
import "./App.css";
import Login from "./components/Login";
import Profile from "./components/Profile";
import UserContextProvider from "./contexts/UserContextProvider";

function App() {
  return (
    // Wrap all the components with UserContextProvider
    <UserContextProvider>
      <h1>Welcome to Koushik Codes</h1>
      <Login />
      <Profile />
    </UserContextProvider>
  );
}

export default App;
// src/components/Login.tsx
import { useState } from "react";
import { useUserContext } from "../contexts/UserContextProvider";

export default function Login() {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  // using custom hook
  const { setUser } = useUserContext();

  const handleSubmit = (e: any) => {
    e.preventDefault();
    setUser({ username, password });
  };
  return (
    <div>
      <input
        type="text"
        value={username}
        onChange={(e) => setUsername(e.target.value)}
        name="username"
        id="username"
        placeholder="username"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        name="password"
        id="password"
        placeholder="password"
      />
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
}
// src/components/Profile.jsx
import { useUserContext } from "../contexts/UserContextProvider";

export default function Profile() {
  // using custom hook
  const { user } = useUserContext();
  if (!user) return <div>Please login</div>;

  return <div>Welcome {user.username}</div>;
}

Connect With me:
LinkedIn: LinkedIn

Twitter(X): Twitter(X)

0
Subscribe to my newsletter

Read articles from Koushik Roy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Koushik Roy
Koushik Roy

Full-stack Dev | Open Source Contributor | Next.js | Nest.js (Node) | SQL | NoSQL | Prisma | Tailwind | Web3 Learner | Building diarist.life