0

I am trying to fetch some data from the API and setting the data in my redux store. However, when I try to do some operation with the data from the redux store that variable is empty. I have used await but it seems it does not work. However, after useEffect the redux store(api data) data is visible and can do operations on it. Any help is appreciated. Please note I need to access the redux store field not just get the returned data from the function. Accessing the redux store field is important. Here is my code:

useEffect(() => {
    async function loadData() {
      const startingDateYear = moment();
      const eventDates = generateDatesForYear(startingDateYear.year().toString());
      await dispatch(fetchData('0009', eventDates[0], eventDates[1]));
    }
    loadData();
    console.log(event.myDataArray) // event is a reducer and myDataArray is the field. It can be accessed outside the function with data incorporated but within useEffect I am not able to use the freshly fetched data.
    return {};
  }, []);


 export const fetchData = (p1, p2, p3) => {
  return async dispatch => {
    const path = `dataFromAPIURL`;
    try {
      dispatch({
        type: FETCH_STARTED,
      });

      const myDataArray = await RestService.get(path);
      dispatch({
        type: FETCH_FINISHED,
      });

      dispatch({
        type: UPDATE_REDUCER_STATE,
        payload: myDataArray,
      });

      return myDataArray;
    } catch (error) {
      // TODO: error handling
      dispatch({ type: FETCH_ERROR, payload: error });
    }
  };
};
Hassan Abbas
  • 1,166
  • 20
  • 47
  • 1
    You defined loadData as an async function, but you are not calling it with await – Patrick Hund Mar 05 '20 at 13:23
  • Even If I use await there and make useEffect Async it still does not work since I need to access the redux store field. And yes making useEffect async does not seem the most elegant solution at this point. – Hassan Abbas Mar 05 '20 at 13:36

1 Answers1

1

You need a second useEffect with dependency event.myDataArray

useEffect(() => {
  async function loadData() {
    const startingDateYear = moment();
    const eventDates = generateDatesForYear(startingDateYear.year().toString());
    await dispatch(fetchData("0009", eventDates[0], eventDates[1]));
  }
  loadData();
}, []);

useEffect(() => {
  console.log(event.myDataArray);
}, [event.myDataArray]);
SuleymanSah
  • 17,153
  • 5
  • 33
  • 54
  • It does work but why do I need a second useEffect? Shouldnt await be sufficient since I just need to wait for my dispatches to finish ? – Hassan Abbas Mar 05 '20 at 13:43
  • My useEffect is more like component did mount and adding a second effect would make things more complicated since I think it is not needed. – Hassan Abbas Mar 05 '20 at 13:45
  • It would be super nice If we could do it with one useEffect as previously withCompnent Did Mount? – Hassan Abbas Mar 05 '20 at 13:45
  • 1
    @HassanAbbas you can't directly access it in the first useEffect, this is the nature of useEffect. – SuleymanSah Mar 05 '20 at 13:46
  • 1
    @HassanAbbas you can learn more about this in this [docs](https://reactjs.org/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns) – SuleymanSah Mar 05 '20 at 13:49
  • Also https://stackoverflow.com/questions/54002792/should-i-use-one-or-many-useeffect-in-component is helpful. – SuleymanSah Mar 05 '20 at 13:52