Lädt...

🔧 React Context-API Pro | Build state management using useContext + useReducer | Typescript


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

The Context API in React is a powerful feature that allows you to manage state globally across your application without the need to pass props down through multiple levels of your component tree. When combined with TypeScript, it becomes even more robust, providing type safety and better code maintainability. In this article, I'll walk you through setting up a Context API for authentication in a React app using modern conventions and TypeScript.

Project Structure

First, let's outline the project structure. We'll split our Context setup into four separate files:

context.tsx: This file will create and export the context.
provider.tsx: This file will provide the context to the component tree.
reducer.ts: This file will define the initial state and reducer function.
actions.ts: This file will contain action creators.
state.ts: This file will contain the initial state of the context
useAuthContext.ts: This file contain a custom hook which will help to call context

Image description

01. Creating the Context

We'll start by creating the context.tsx file. This file will initialize the context and provide a custom hook for easy access.

import { createContext } from "react";
import { AuthContextProps } from "../types";

export const AuthContext = createContext<AuthContextProps | undefined>(undefined);

02. Defining the Initial State of the Context

After that we will define the initial state for the context in the state.ts. This initial state will be use for storing all the datas.

import { AuthState } from "../types";

export const initialState: AuthState = {
  isAuthenticated: false,
  user: null,
  token: null,
};

03. Setting Up the Provider

Next, we'll set up the provider in the provider.tsx file. This component will use the useReducer hook to manage the state and pass it down via the context provider.

import React, { useReducer } from "react";
import { AuthProviderProps } from "../types";
import { AuthContext } from "./context";
import { AuthReducer } from "./reducer";
import { initialState } from "./state";

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [state, dispatch] = useReducer(AuthReducer, initialState);

  return <AuthContext.Provider value={{ state, dispatch }}>{children}</AuthContext.Provider>;
};

04. Defining the Reducer

The reducer is the heart of our state management. In the reducer.ts file, we'll define our initial state and the reducer function to handle actions.

import { AuthAction, AuthState } from "../types";

export const AuthReducer = (state: AuthState, action: AuthAction): AuthState => {
  switch (action.type) {
    case "LOGIN":
      return {
        ...state,
        isAuthenticated: true,
        user: action.payload.user,
        token: action.payload.token,
      };
    case "LOGOUT":
      return {
        ...state,
        isAuthenticated: false,
        user: null,
        token: null,
      };
    default:
      return state;
  }
};

05. Creating Actions

Action creators make it easier to dispatch actions in a type-safe way. We'll define these in the actions.ts file.

import { AuthAction, IUser } from "../types";

export const login = (user: IUser, token: string): AuthAction => {
  return {
    type: "LOGIN",
    payload: { user, token },
  };
};

export const logout = (): AuthAction => {
  return { type: "LOGOUT" };
};

06. Configure the custom-hook.

This custom will help use set and call the context in any components without involving multiple parameters into it. Create a file and name it useAuthContext.ts.

import { useContext } from "react";
import { AuthContext } from "./context";

export const useAuthContext = () => {
  const context = useContext(AuthContext);
  if (!context) throw new Error("Error: useAuth must be within in AuthProvider");
  return context;
};

We are set with all the initial configuration for the state management; now we will see how we can utilize this in our application.

Using the Context

To utilize our new AuthContext, we need to wrap our application (or part of it) in the AuthProvider. We'll do this in our main entry point, typically App.tsx.

import React from "react";
import { AuthProvider } from "./context/provider";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./Home";

const App: React.FC = () => {
  return (
    <AuthProvider>
      <Router>
        <Routes>
          <Route path="/" element={<Home />} />
        </Routes>
      </Router>
    </AuthProvider>
  );
};

export default App;


Within any component, we can now use the useAuth hook to access the auth state and dispatch actions. Here's an example component that uses our AuthContext:


import React from "react";
import { useAuthContext } from "./context/useAuthContext";
import { IUser } from "./types";
import { login, logout } from "./context/actions";

const Home: React.FC = () => {
  const { state, dispatch } = useAuthContext();

  const handleLoginClick = () => {
    const user: IUser = { firstName: "John", lastName: "Doe", role: "SUPER-ADMIN" };
    const token = "dfs56ds56f5.65sdf564dsf.645sdfsd4f56";
    dispatch(login(user, token));
  };

  const handleLogoutClick = () => dispatch(logout());

  return (
    <div>
      <h1>Home Page</h1>
      {state.isAuthenticated ? (
        <div>
          <h3>Welcome {state.user?.firstName}</h3>
          <button onClick={handleLogoutClick}>Logout</button>
        </div>
      ) : (
        <button onClick={handleLoginClick}>Login</button>
      )}
    </div>
  );
};

export default Home;

Types & Interfaces

import { Dispatch, ReactNode } from "react";

export interface IUser {
  firstName: string;
  lastName: string;
  role: "SUPER-ADMIN" | "ADMIN" | "USER";
}

export interface AuthState {
  isAuthenticated: boolean;
  user: null | IUser;
  token: null | string;
}

export interface AuthContextProps {
  state: AuthState;
  dispatch: Dispatch<AuthAction>;
}

export interface AuthProviderProps {
  children: ReactNode;
}

export type AuthAction =
  | { type: "LOGIN"; payload: { user: IUser; token: string } }
  | { type: "LOGOUT" };

Conclusion

By following this structured approach, you can manage global state in your React applications more effectively. The Context API, when used with TypeScript, provides a powerful and type-safe solution for state management. This setup is not only limited to authentication but can be adapted for other use cases like theme management, language settings, and more.

With this knowledge, you can now use Context-API like a pro! Feel free to modify and extend this setup to fit the needs of your own projects.

...

🔧 State Management with useContext and useReducer in React: Building a Global Shopping Cart


📈 57.25 Punkte
🔧 Programmierung

🔧 Mastering State Management in React: A Guide to useContext and useReducer Hooks


📈 57.25 Punkte
🔧 Programmierung

🔧 Tutorial Guide to 'useContext' and 'useReducer' in React: Managing Global State Efficiently


📈 53.92 Punkte
🔧 Programmierung

🔧 When to Use useState, useReducer, and useContext in React


📈 47.41 Punkte
🔧 Programmierung

🔧 react 19 useContext, useReducer & localstorage


📈 47.41 Punkte
🔧 Programmierung

🔧 Navigating React State: useState, useReducer, Context, Redux Toolkit, Recoil


📈 42.4 Punkte
🔧 Programmierung

🔧 useContext + useReducer vs Redux


📈 42.01 Punkte
🔧 Programmierung

🔧 🚀 Day 12: Enhancing State Management using useReducer in React 🚀


📈 39.23 Punkte
🔧 Programmierung

🔧 🚀 Day 12: Enhancing State Management using useReducer in React 🚀


📈 39.23 Punkte
🔧 Programmierung

🔧 Mastering State Management with the useReducer Hook in React


📈 35.42 Punkte
🔧 Programmierung

🔧 State Management in React: When to Use useState, useReducer, and useRef


📈 35.42 Punkte
🔧 Programmierung

🔧 Mastering React State Management with useReducer: A Comprehensive Guide


📈 35.42 Punkte
🔧 Programmierung

🔧 Revolutionize Your React App with useReducer: Mastering State Management


📈 35.42 Punkte
🔧 Programmierung

🔧 Safe component state with useReducer and TypeScript


📈 35.1 Punkte
🔧 Programmierung

🔧 Mastering React's useReducer Hook: Managing Complex State with Actions


📈 32.08 Punkte
🔧 Programmierung

🔧 Simplifying state management with useReducer hook


📈 30.02 Punkte
🔧 Programmierung

🔧 Smart Dropdowns in React: Using useReducer and useRef for Outside Click Handling


📈 29.39 Punkte
🔧 Programmierung

🔧 useReducer: Beyond useState for Complex State Logic


📈 26.68 Punkte
🔧 Programmierung

🔧 Simplifying React Hooks: useReducer 💯


📈 25.58 Punkte
🔧 Programmierung

🔧 Hook guide:useReducer() in react


📈 25.58 Punkte
🔧 Programmierung

🔧 useReducer: React Hooks


📈 25.58 Punkte
🔧 Programmierung

🔧 React Basics~useReducer/ countup


📈 25.58 Punkte
🔧 Programmierung

🔧 Redux vs React’s useReducer


📈 25.58 Punkte
🔧 Programmierung

🔧 Entendendo o useReducer do React


📈 25.58 Punkte
🔧 Programmierung

🔧 How to Use the useReducer Hook in React


📈 25.58 Punkte
🔧 Programmierung

🔧 Understanding useReducer Hook in React – An introduction and a Comprehensive Guide for Web Developers


📈 25.58 Punkte
🔧 Programmierung

🔧 UseReducer React Hook Well Explained


📈 25.58 Punkte
🔧 Programmierung

🔧 How to Create an Inventory List with React useReducer, Axios, and JSON Server


📈 25.58 Punkte
🔧 Programmierung

🔧 React useReducer() 🪝


📈 25.58 Punkte
🔧 Programmierung

🔧 Os 10 React Hooks Mais Úteis: 05 - useReducer


📈 25.58 Punkte
🔧 Programmierung

🔧 Understanding the useReducer hook in react


📈 25.58 Punkte
🔧 Programmierung

🔧 useReducer hook in React (No redux here)


📈 25.58 Punkte
🔧 Programmierung

🔧 useReducer for dummies(kid friendly)


📈 20.18 Punkte
🔧 Programmierung

🔧 useState vs useReducer - choose your champion 🤺


📈 20.18 Punkte
🔧 Programmierung