I have a react controler that call a endpoint. When I get the response I display the information in an object and I want to change a color of a buton to represent if the response was a 200 or a 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;
So in the code, because axios is async, this will receive the response after finish the method onClick in the buton but the buton won't change color. Can someone helps?
CodePudding user response:
I think that you shold move the llamadaAxiosGet
function call in the BotonLlamada
component and pass the setPersonGet
state property to it:
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;
CodePudding user response:
Your issue is that you're setting your state to a promise of number.
A simple fix would be:
const onClickbuton = () => {
props.llamadaAxiosGet(props.url)
.then(status => setEstado(status));
};
You could also refactor and shift your logic up to the parent component.
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;