juanl4zy
juanl4zy

Reputation: 65

React setState not updating the state object

Debugging: Inside the functions declared in AuthProvider, I coded a console.log() and its working. The setState that updates the state object is not updating its value. Why?

Seems like I'm missing something. Can you help me out?

AuthContext.tsx

import React, { useState } from "react";
import { AuthContextType, User } from "../@types/auth";

export const AuthContext = React.createContext<AuthContextType | null>(null);

const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const [user, setUser] = useState<User>({
        auth: false,
        currentUrl: "",
    });

    const updateAuth = () => {
        console.log("Hello, world!")
        setUser({ ...user, auth: !user.auth });
    }

    const updateUrl = (url: string) => {
        setUser(user => ({
            ...user,
            currentUrl: url,
        }));
    }

    return (
        <AuthContext.Provider value={{ user, updateAuth, updateUrl }}>
            {children}
        </AuthContext.Provider>
    );
};

export default AuthProvider;

auth.d.ts

export type User = {
    auth: boolean;
    currentUrl: string;
}

export type AuthContextType = {
    user: User;
    updateAuth: () => void;
    updateUrl: (url: string) => void;
}

export type LoginCredentials = {
    email: string;
    password: string;
}

Login.tsx

const { updateAuth } = useContext(AuthContext) as AuthContextType;
if (response.data) {
                updateAuth();
}
**App.tsx**
import AppRouter from "./routes/AppRouter";
import AuthProvider from "./components/AuthContext";

function App() {
  return (
      <AuthProvider>
        <AppRouter />
      </AuthProvider>
  );
}

export default App;

Upvotes: 1

Views: 668

Answers (1)

Phaki
Phaki

Reputation: 315

In the updateAuth function inside your AuthProvider component, you are using the state variable user directly to update its value. However, React's state updates may be asynchronous, and when you use the state directly inside the function argument of setUser, it might not reflect the latest state.

const updateAuth = () => {
    console.log("Hello, world!");
    setUser(prevUser => ({ ...prevUser, auth: !prevUser.auth }));
}

Similarly, you can also apply this pattern in the updateUrl function:

const updateUrl = (url: string) => {
    setUser(prevUser => ({
        ...prevUser,
        currentUrl: url,
    }));
}

Upvotes: 1

Related Questions