Tengo un archivo api.js con la siguiente función:
export const login = (loginUserName, loginPassword, setUser) => { axios({ method: 'post', data: { username: loginUserName, password: loginPassword }, withCredentials: true, url: '...........' }).then(async (res) => { if (res.data.loggedIn === true) setUser(loginUserName); }); };Mis ganchos useState tienen el siguiente aspecto:
const [ user, setUser ] = useState({});Me preguntaba, en lugar de enviar la función setUser desde mi componente de inicio de sesión como lo hago yo:
login(userName,password,setUser);que está en otro archivo, ¿cómo puedo hacerlo desde fuera de la función como la siguiente:
setUser(login(userName,password));Entonces, en caso de que la función recupere la información que quería, la devolverá (en este caso, el nombre de usuario), y en caso contrario, configurará al usuario como indefinido o algo así.
Traté de usar
export const login = (loginUserName, loginPassword) => { axios({ method: 'post', data: { username: loginUserName, password: loginPassword }, withCredentials: true, url: '............' }).then(async (res) => { if (res.data.loggedIn === true) return loginUserName; }); };Pero tuve algunos problemas con la función asíncrona. Parece que no devolverá esa información por alguna razón. si tuviera que adivinar, lo devuelve solo para la función axios o algo así. ¿Cómo obtengo el efecto que estoy buscando y cuál es la mejor práctica? ¿El envío de la función "setUser" se considera una buena práctica o es mejor intentar deshacerse de ella?
Su función setUser solo es válida dentro de un componente que lo declara, así que sí, simplemente devuelva el resultado de búsqueda y maneje la configuración del estado dentro de ese componente en particular.
Y la razón por la que no obtiene nada devuelto podría ser que la solicitud no tuvo éxito (verifique la pestaña de red de su navegador y la respuesta relevante) o que no await el resultado (la obtención es siempre una operación asincrónica, por lo que tiene esperar la respuesta con un retraso).
Podrías hacer algo como esto:
useEffect(() => { (async () => { const username = await login(userName,password,setUser); setUser(username); })(); }, []);Si necesito un objeto de estado que necesito usar a lo largo del flujo de mi aplicación, como un objeto de usuario que planeo pasar a la mayoría de los componentes secundarios. Entonces prefiero usar la biblioteca Redux para crear una tienda a la que pueda acceder en todos los componentes.
Habría mucho que hacer para que funcione, por lo que tendría cuidado al leer la Documentación , pero vale la pena trabajar con las herramientas proporcionadas.
Luego puede acceder/manipular estados de la tienda como los siguientes:
import React, { useState } from 'react'; import { useAppSelector, useAppDispatch } from 'app/hooks'; import { decrement, increment } from './counterSlice'; function login(loginUserName, loginPassword) { const dispatch = useAppDispatch(); axios({ method: 'post', data: { username: loginUserName, password: loginPassword }, withCredentials: true, url: '............' }).then(async (res) => { if (res.data.loggedIn === true) { dispatch(setUser(loginUserName)); } }; } export function Login() { login("User Name", "********"); const user = useAppSelector((state) => state.user.value); console.log(user); }