简体   繁体   中英

Data is not updating with React Hook useEffect()

I have a little web application that uses axios to fetch some orders from the API. My problem is the new orders only appear when the page is refreshed, they do not update automatically.

Here is my useEffect hook:

useEffect(() => {
    setLoading(true);
    apiClient
      .getEvents()
      .then((res) => {
        console.log(res);
        setOrders(res.data);
        setLoading(false);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

And here is where I use axios:

import axios from "axios";

const username = "user";
const password = "pass";

const token = Buffer.from(`${username}:${password}`, "utf8").toString("base64");

const apiClient = axios.create({
  baseURL: "API URL",
  withCredentials: false,
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json",
    Authorization: `Basic ${token}`,
  },
});

export default {
  getEvents() {
    return apiClient.get("/orders");
  },
  getEvent(order_id) {
    return apiClient.get("/orders/" + order_id);
  },
};

Your problem ist the useEffect-Hook itself.

useEffect(() => {
    setLoading(true);
    apiClient
      .getEvents()
      .then((res) => {
        console.log(res);
        setOrders(res.data);
        setLoading(false);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

You pass an empty array as the second argument here: }, []); . When you pass an empty array as second argument to useEffect , it will only run on first mount and then never again.

You can pass different variables in this parameter. In this case, useEffect will run, when of these variables change their value. So, for example, you could have a "Refresh" button which changes a state called refresh which you then pass as a second argument to useEffect .

const [refresh, setRefresh] = useState(false);

useEffect(() => {
    if(!refresh) return;
    setLoading(true);
    apiClient
      .getEvents()
      .then((res) => {
        console.log(res);
        setOrders(res.data);
        setLoading(false);
        setRefresh(false);
      })
      .catch((err) => {
        console.log(err);
      });
  }, [refresh]);

Just a simple example, it could be done better, of course.

Also, one hint: You can omit the second parameter, the dependency array, of useEffect , which would make it run on every update of your component. Don't do this. In most cases, you will end up in an infinite loop because most of the time you will update the state and cause the component to rerender within useEffect - in your case, using setLoading() would be enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM