reactjs - La propiedad '' no existe en el tipo '{}'
Estoy intentando configurar un hook de contexto para usarlo en mi página de inicio de sesión. Estoy usando Typescript. Comencé el hook de contexto, pero estoy teniendo problemas con la declaración de tipos. Cuando intento usar setUser, aparece este error: La propiedad 'setUser' no existe en el tipo '{}'.
Aquí está mi gancho de contexto hasta ahora.
import { createContext, ReactNode, useEffect, useState } from "react"
interface Props {
children?: ReactNode
}
export const UserContext = createContext({})
export function UserContextProvider({children}: Props) {
const [user, setUser] = useState(null)
return (
<UserContext.Provider value={{user, setUser}}>
{children}
</UserContext.Provider>
)
}
Y aquí está mi código de inicio de sesión.
import { Link, Navigate } from "react-router-dom"
import axios from 'axios'
import { UserContext } from "../UserContext"
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [redirect, setRedirect] = useState(false)
**const {setUser} = useContext(UserContext)**
async function handleLogin(e: any) {
e.preventDefault()
try {
const userInfo = await axios.post('/auth/login', {email, password})
setUser(userInfo)
alert('Login')
setRedirect(true)
} catch (e) {
alert('Login failed')
}
}
if(redirect){
return <Navigate to={'/'} />
}
return (
<div>
<div>
<h1>Login</h1>
<form onSubmit={handleLogin}>
<input type="email" placeholder="[email "
value={email} onChange={e => setEmail(e.target.value)}/>
<input type="password" placeholder="password"
value={password} onChange={e => setPassword(e.target.value)}/>
<button>Login</button>
<div>
Don't have an account?
<Link to={"/auth/register"}> Sign Up</Link>
</div>
</form>
</div>
</div>
)
}
export default Login
Respuesta #1
Necesitas especificar un tipo para tu variable UserContext. Debido a que le has dado un argumento de {} en createContext, TypeScript asume que el contexto tiene un tipo de React.Context<{}>. Por lo tanto, cuando intentas usar el objeto de contexto, obtienes un {}, un objeto vacío, que no tiene propiedades definidas por el usuario.
Para empezar, definiré una nueva interfaz, pero puedes escribirla como quieras.
interface IUserContext {
user: any;
setUser: any; //set your definitions here (please don't use `any`)
}
Para declarar el tipo de UserContext, puedes:
Proporcione un valor predeterminado que coincida con el tipo
export const UserContext = createContext<IUserContext>("<defaultValueHere>");Establece el valor de contexto predeterminado como un objeto nulo/vacío
export const UserContext = createContext<IUserContext|{}>({}); export const UserContext = createContext<IUserContext|null>(null);Convertir un objeto vacío a un tipo (menos seguro en cuanto al tipo)
export const UserContext = createContext<IUserContext>({} as IUserContext);Aserción de no nulo (menos segura para el tipo)
export const UserContext = createContext<IUserContext>(null!);
Tenga en cuenta que para algunos de estos, necesitará escribir comprobaciones de null más adelante. Vea aquí para más información.
