# React Context API with TypeScript

### **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:

```typescript
// 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

```typescript
// 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;
```

```typescript
// 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>
  );
}
```

```javascript
// 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](https://www.linkedin.com/in/koushik-roy-886804280/)

Twitter(X): [Twitter(X)](https://twitter.com/KoushikRoy75724)
