Tengo un controlador de reacción que llama a un punto final. Cuando obtengo la respuesta, muestro la información en un objeto y quiero cambiar el color de un botón para representar si la respuesta fue 200 o 404.
import React, { useState, useEffect } from "react"; import "./../App.css"; import axios from "axios"; const MicroService = (props) => { const [personsGet, setPersonGet] = useState([]); function llamadaAxiosGet (url) { axios .get(url) .then((res) => { setPersonGet(res.data); return res.status; }) .catch(function (error) { return error.status; }); } return ( <div> <h2>Microservicio:</h2> <BotonLlamada url={`https://jsonplaceholder.typicode.com/users`} textBoton={"Llamada al servicio y display all"} llamadaAxiosGet={llamadaAxiosGet} /> {personsGet.map((person) => ( <li key={person.name}>{person.name}</li> ))} </div> ); }; function BotonLlamada(props) { const [colorButon, setColorButon] = useState(""); const [estado , setEstado]= useState(0); const onClickbuton = () => { setEstado(props.llamadaAxiosGet(props.url)); setEstado(props.llamada); if (estado === 200) { setColorButon("buttonGreen"); } else if (estado > 399) { setColorButon("buttonRed"); } }; useEffect(() => { if (estado > 399) { setColorButon("buttonRed"); } else if (estado === 200) { setColorButon("buttonGreen"); } },[estado]); return ( <div> <button onClick={onClickbuton} className={colorButon}> {props.textBoton} </button> <br /> </div> ); } export default MicroService;Entonces, en el código, debido a que axios es asíncrono, recibirá la respuesta después de finalizar el método al hacer clic en el botón, pero el botón no cambiará de color. ¿Alguien puede ayudar?
Creo que deberías mover la llamada a la función llamadaAxiosGet en el componente BotonLlamada y pasarle la propiedad de estado setPersonGet :
const MicroService = (props) => { const [personsGet, setPersonGet] = useState([]); return ( <div> <h2>Microservicio:</h2> <BotonLlamada textBoton={"Llamada al servicio y display all"} setPersonGet={setPersonGet} /> {personsGet.map((person) => ( <li key={person.name}>{person.name}</li> ))} </div> ); }; function BotonLlamada(props) { const [colorButon, setColorButon] = useState(""); const [estado , setEstado]= useState(0); function llamadaAxiosGet () { axios .get(`https://jsonplaceholder.typicode.com/users`) .then((res) => { props.setPersonGet(res.data); setEstado(res.status); setColorButon("buttonGreen"); }) .catch(function (error) { setEstado(error.status); setColorButon("buttonRed"); }); } useEffect(() => { if (estado > 399) { setColorButon("buttonRed"); } else if (estado === 200) { setColorButon("buttonGreen"); } },[estado]); return ( <div> <button onClick={() => llamadaAxiosGet() } className={colorButon}> {props.textBoton} </button> <br /> </div> ); } export default MicroService;Su problema es que está configurando su estado en una promesa de número.
Una solución simple sería:
const onClickbuton = () => { props.llamadaAxiosGet(props.url) .then(status => setEstado(status)); };También puede refactorizar y cambiar su lógica al componente principal.
import React, { useState } from "react"; import "./../App.css"; import axios from "axios"; function BotonLlamada({ colour, onClick, textBoton }) { return ( <div> <button onClick={onClick} className={colour}> {textBoton} </button> <br /> </div> ); } const MicroService = (props) => { const [personsGet, setPersonGet] = useState([]); const [colour, setColour] = useState(""); function llamadaAxiosGet(url) { axios .get(url) .then((res) => { setPersonGet(res.data); return res.status; }) .catch(function (error) { return error.status; }) .then((status) => { if (status > 399) { setColour("buttonRed"); } else if (status === 200) { setColour("buttonGreen"); } }); } return ( <div> <h2>Microservicio:</h2> <BotonLlamada textBoton={"Llamada al servicio y display all"} onClick={() => llamadaAxiosGet(`https://jsonplaceholder.typicode.com/users`) } colour={colour} /> {personsGet.map((person) => ( <li key={person.name}>{person.name}</li> ))} </div> ); }; export default MicroService;