Tengo un problema al intentar guardar en Estado una llamada a la API de axios. Probé el método useState set que no refleja el cambio inmediatamente en la respuesta y muchos otros y no puedo guardar el estado. Esto no es un duplicado, porque probé cuál es la respuesta aceptada y la siguiente y todavía no funciona. Aquí está el componente (bastante simple). Cualquier ayuda será apreciada
export const Home = () => { const [widgets, setWidgets] = useState([]); useEffect(() => { axios .get('/call-to-api') .then((response) => { const data = response.data; console.log(data); // returns correctly filled array setWidgets(widgets, data); console.log(widgets); // returns '[]' }); }, []); // If I set 'widgets' here, my endpoint gets spammed return ( <Fragment> {/* {widgets.map((widget) => { // commented because it fails <div>{widget.name}</div>; })} */} </Fragment> ); };Bienvenido a stackoverflow, lo primero es lo primero: la llamada de configuración es incorrecta, debe usar el operador de distribución para combinar la matriz en una, así que cámbielo a setWidgets([...widgets, ...data]); sería correcto (supongo que tanto los widgets como data son Array)
segundo, el estado de reacción no cambiará sincrónicamente
.then((response) => { const data = response.data; console.log(data); // returns correctly filled array setWidgets(widgets, data); console.log(widgets); // <--- this will output the old state since the setWidgets above won't do it's work till the next re-render entonces, para escuchar el cambio de estado, debe usar useEffect hook
useEffect(() => { console.log("Changed Widgets: ", widgets) }, [widgets])esto registrará la consola cada vez que cambie el widget
el código completo se verá así
export const Home = () => { const [widgets, setWidgets] = useState([]); useEffect(() => { axios .get('/call-to-api') .then((response) => { const data = response.data; setWidgets([...widgets, ...data]) }); }, []); useEffect(() => { console.log("Changed Widgets: ", widgets) }, [widgets]) return ( <Fragment> {/* {widgets.map((widget) => { // commented because it fails <div>{widget.name}</div>; })} */} </Fragment> ); };Probar:
setWidgets(data);en lugar de
setWidgets(widgets, data);Su widgets.map() probablemente falla porque no hay mucho que mapear cuando se procesa el componente.
Debe actualizarlo con un condicional como este, solo para mayor claridad:
widgets.length>0 ? widgets.map(...) : <div>No results</div>Y su llamada a setWidgets() solo debe tomar un argumento, los datos:
setWidgets(data)o si desea fusionar las matrices, use un operador de distribución (pero luego debe agregar widgets como dependencia a la matriz de dependencia useEffect).
setWidgets(...widgets, ...data)Es posible que también deba proporcionar la función de enlace setWidgets a la matriz de dependencias useEffect.
Déjeme saber si esto ayuda..