Search code examples
reactjsreact-context

React UseContext not updating state


I am attempting to update state using a context provider. I cannot figure out where I am going wrong.

The state simply doesn't update. If anyone could point me in the right direction or suggest resources I can consult, I would be eternally grateful.

My code is below:

// App.tsx
import "./styles.css";
import MyComponent from "./MyComponent";
import { AuthProvider } from "./AuthContext";

export default function App() {
  return (
    <AuthProvider>
      <MyComponent />
    </AuthProvider>
  );
}


//MyComponent.tsx
import "./styles.css";
import { useAuth } from "./AuthContext";

export default function MyComponent() {
  const { user, setUser } = useAuth();
  return (
    <div>
      <div className="App">
        <h1>Hello {user.name} How are you today?</h1>
      </div>
      <button
        onClick={() => {
          setUser({ name: "Registered User" });
        }}
      >
        Update User
      </button>
    </div>
  );
}

// AuthContext.tsx
import { createContext, useContext, useState, ReactNode } from "react";

// Define an interface for the context value
interface AuthContextType {
  user: any;
  setUser: (authUser: any) => void;
}

// Create the context with a default value
let defaultAuthContext: AuthContextType = {
  user: { name: "Guest" },
  setUser: (authUser: any) => {},
};

export const AuthContext = createContext<AuthContextType>(defaultAuthContext);

interface AuthProviderProps {
  children: ReactNode;
}

export const AuthProvider = ({ children }: AuthProviderProps) => {
  const [user, setUser] = useState();

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

export const useAuth = (): AuthContextType => {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
};

I have created a codesandbox showing the issue I have encountered https://codesandbox.io/p/sandbox/4vw2yq

Update (What I have tried): I moved the useAuth call into its own child component, however the behavior is still the same.


Solution

  • const [user, setUser] = useState<any>({ name: "Guest" });
    

    Explanation:

    Without proper initialisation of the user state, the user object may be undefined, causing issues when trying to access user.name. By initialising the state with a default value ({ name: "Guest" }), the application behaves as expected, and the state updates correctly when setUser is called.