Home > Software engineering >  Change buton color when get axios response
Change buton color when get axios response

Time:11-26

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;
  • Related