简体   繁体   中英

How to modify data after waiting for it to be fetched react axios

I'm trying to get data from my API then modifying it, I tried this:

const [reports, setReports] = useState([]);
const [workers, setWorkers] = useState([]);
const [newReports, setNewReports] = useState([]);

useEffect(() => {
  (async () => {
    await get_user_data().then((dataRes) => {
      axios
        .get('/api/reports/?my_business=' + dataRes.id)
        .then((dataRes) => {
          setReports(dataRes.data);
          return dataRes.data[0].my_business;
        })
        .then((dataRes) => {
          axios
            .get('/api/workers/?my_business=' + dataRes)
            .then((dataRes) => {
              setWorkers(dataRes.data);
            })
            .then(() => {
              setNewReports(fix_data());
            });
        });
    });
  })();
}, []);

I got the reports and the workers , but when I set newReports I only get them in the first render, if I refresh I lose the data in new reports, that's because setNewReports(fix_data()) don't wait for the reports and the workers to be fetched.

Here's my fix_data() function:

function fix_data() {
  let w = {};
  let r = {};
  let rep = [];

  reports.forEach((report) => (w[report.worker_id] = workers.find((worker) => worker.id === report.worker_id)));
  reports.forEach(
    (report) => (
      (r = report), (r.worker_id = w[report.worker_id].first_name + ' ' + w[report.worker_id].last_name), rep.push(r)
    ),
  );
  return rep;
}

What's wrong with my useEffect function? I do call setNewReports(fix_data()) inside then so why it doesn't wait for the data to be fetched? Thank you

const [reports, setReports] = useState([]);
const [workers, setWorkers] = useState([]);
const [newReports, setNewReports] = useState([])

const get_reports = async (dataRes) =>{
   const Report_Res = await axios.get('/api/reports/?my_business=' + dataRes.id)
   setReports(Res.data); 
} 

const get_worker_data = async (dataRes)=>{
   const Worker_Res = await axios.get('/api/workers/?my_business=' + dataRes)
   setWorkers(dataRes.data);
}

useEffect(()=>{
  get_user_data()
},[])

useEffect(()=>{
  get_reports(dataRes)
  get_worker_data(dataRes)
},[dataRes])

useEffect(()=>{
  setNewReports(fix_data())
},[reports, workers])

@alaa yahia It's better if you practice clean code. :)

1.Try to wrap up your each api call in separate function. It looks cleaner and easy to understand.

  1. Call the functions in useEffect. Look at the 1st useEffect. they will populate the states of user Data. 2nd useEffect fetches the worker and report data which depends on DataRes. So add DataRes in dependency array of 2nd useEffect.

  2. call the setNewReports(fix_data()) in 3nd useEffect. and it will make sure It fixes the data when reports and workers data are present. Look at the dependency array- [reports, workers] at the end of 3rd useeffect. That means This useEffect will run, when these [reports, workers] changes.

NB- I wrote those codes without running. Forgive if any Typing mistake presents.

Here's the code that worked after small fixes on @black lotus's answer :

const [reports, setReports] = useState([]);
const [workers, setWorkers] = useState([]);
const [newReports, setNewReports] = useState([]);
const [dataRes, setDataRes]= useState([]);

const get_reports = async (dataRes) =>{
const Report_Res = await axios.get('/api/reports/?my_business=' + dataRes)
setReports(Report_Res.data);
}

const get_worker_data = async (dataRes)=>{
   const Worker_Res = await axios.get('/api/workers/?my_business=' + dataRes)
   setWorkers(Worker_Res.data);
}
const get_user = async (dataRes)=>{
   const user_Res = await get_user_data()
   setDataRes(user_Res);
}

useEffect(()=>{
  get_user()
},[])

useEffect(()=>{
  get_worker_data(dataRes)
  get_reports(dataRes)

},[dataRes])

useEffect(()=>{
  setNewReports(fix_data())
},[reports, workers])

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