Búsqueda de sitios web

reactjs - TypeScript con useContext de React? la propiedad no existe


Intentando usar TypeScript con useContext de React. Pensé que lo había entendido, pero recibo un error que indica que las props no existen cuando desestructuro el hook personalizado.

Aquí está mi hook personalizado: no veo errores de TypeScript desde lo que veo

type AppContext = {
  handleLogin: HandleLogin;
};

type HandleLogin = (email: string, password: string) => void;

const AuthContext = createContext<AppContext | null>(null);

export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
  const [user, setUser] = useState(null);

  const router = useRouter();

  // Handle login
  const handleLogin: HandleLogin = async (email: string, password: string) => {
    const userData = await login(email, password);
    setUser(userData);
  };

  return (
    <AuthContext.Provider value={{ handleLogin }}>
      {children}
    </AuthContext.Provider>
  );
};

Pero cuando desestructuro el hook así...

  const { handleLogin } = useAuth();

Recibo el siguiente error - * La propiedad 'handleLogin' no existe en el tipo 'AppContext | null'.*

Recibo el mismo error si incluyo otro valor o función dentro del valor del contexto, pero me encuentro con el mismo error. Realmente no estoy seguro de lo que me falta.

Respuesta #1

Estás asignando el valor inicial de context como null, por lo que necesitas asegurarte de que el context no sea null cuando lo estés reestructurando. O puedes decirle a TypeScript que context siempre será AppContext.

const AuthContext = createContext<AppContext>({} as AppContext);

Es seguro en cuanto al tipo porque el valor se establecerá en el Proveedor cuando tu componente use el contexto.

ACTUALIZACIÓN: Lo siguiente probablemente sea una mejor solución.

const AuthContext = createContext<AppContext|null>(null);

export default function useAuthContext() {
  const context = useContext(AuthContext);
  if (!context) throw Error("useAuthContext can only be used inside an AuthProvider");
  return context;
}

Esto te proporciona seguridad de tipo sin ninguna conversión, además de una verificación en tiempo de ejecución de que el hook se utiliza correctamente. Ten en cuenta que depende de que el valor inicial del contexto sea null.

Respuesta #2

Este error se debe al hecho de que el tipo null no es destructurable en:

const AuthContext = createContext<AppContext | null>(null);

Un mejor enfoque es asignar al valor predeterminado un objeto vacío y declarar su tipo como el tipo de contexto (AppContext):

const AuthContext = createContext< AppContext > ({} as AppContext);

¡Feliz programación!