javascript - Why ASYNC AWAIT doesnt work well in use effect in react - Stack Overflow

im trying to get user location, and then use the location to return relevant data for is location.but i

im trying to get user location, and then use the location to return relevant data for is location.

but in the second function i get that the location is null (when i console.log(location) it prints the right location, at the second print, the first print is null) it seems like the second function is not waiting until the first one is done.

Here is some code:

from the ponent

    const location = useSelector(state => state.locationReducer.location);
    useEffect(()=> {
        (async () => {
            await getLocation();

            // here i'm using the location from the first function
            await getInfo(location);
        })()
    }, []);


    const getLocation = async() => {
        try {
            await dispatch(getLocation());
            console.log(location);
        } catch (err) {
            // TODO HANDLE ERROR;
            console.log('Err:', err);
        }
    }

in the action

export const getLocation = locationName => {
    return async dispatch => {
        try {
            const location = **await** locationService.getLocation(locationName);
            **await** dispatch(setLocation(location));
        } catch (err) {
            throw err;
        };
    };
};

const setLocation = location => {
    return {
        type: types.SET_LOCATION,
        location
    };
};

in service


async function getLocation(locationName) {
    try {]
        return **await** axios.get(`${url}/${locationName}`);
    } catch (err) {
        throw err
    };
};

im trying to get user location, and then use the location to return relevant data for is location.

but in the second function i get that the location is null (when i console.log(location) it prints the right location, at the second print, the first print is null) it seems like the second function is not waiting until the first one is done.

Here is some code:

from the ponent

    const location = useSelector(state => state.locationReducer.location);
    useEffect(()=> {
        (async () => {
            await getLocation();

            // here i'm using the location from the first function
            await getInfo(location);
        })()
    }, []);


    const getLocation = async() => {
        try {
            await dispatch(getLocation());
            console.log(location);
        } catch (err) {
            // TODO HANDLE ERROR;
            console.log('Err:', err);
        }
    }

in the action

export const getLocation = locationName => {
    return async dispatch => {
        try {
            const location = **await** locationService.getLocation(locationName);
            **await** dispatch(setLocation(location));
        } catch (err) {
            throw err;
        };
    };
};

const setLocation = location => {
    return {
        type: types.SET_LOCATION,
        location
    };
};

in service


async function getLocation(locationName) {
    try {]
        return **await** axios.get(`${url}/${locationName}`);
    } catch (err) {
        throw err
    };
};
Share Improve this question edited May 19, 2020 at 6:07 Circus4 asked May 19, 2020 at 5:55 Circus4Circus4 3212 gold badges6 silver badges13 bronze badges 2
  • In your ponent did you tried to use dispatch? There is a useDispatch hook from witch you can get a dispatch instance and in the useEffect your actions need to be wrapped in a dispatch call like: await dispatch(getLocation()); – Martin Commented May 19, 2020 at 6:01
  • i am using dispatch, here is more from the ponent const getLocation = async() => { try { await dispatch(getLocation()); console.log(location); } catch (err) { console.log('Err:', err); } } – Circus4 Commented May 19, 2020 at 6:06
Add a ment  | 

2 Answers 2

Reset to default 3

The location value from the selector won't update after your first function has run and before the second function, so there you'll see the old value in your location variable.

You might need to return your location value from the reducer:

export const getLocation = locationName => {
    return async dispatch => {
        try {
            const location = await locationService.getLocation(locationName);
            await dispatch(setLocation(location));

            return location;
        } catch (err) {
            throw err;
        };
    };
};

And use the returned location in your useEffect:

    useEffect(()=> {
        (async () => {
            const location = await getLocation();

            // here i'm using the location from the first function
            await getInfo(location);
        })()
    }, []);

Or another possibility, to have an another effect, wich depends son the location value:

    const location = useSelector(state => state.locationReducer.location);
    useEffect(()=> {
        getLocation();
    }, []);

    useEffect(()=> {
      if(location) {
        getInfo(location);
      }
    }, [location]);

And this would run every time location changes, and location has some value.

As Per Dan Abramov-

useEffect(() => {
  async function fetchMyAPI() {
    let url = 'http://something';
    let config = {};
    const response = await myFetch(url);
    console.log(response);
  }  
  fetchMyAPI();
}, []);

Here is the link for reference - https://github./facebook/react/issues/14326#issuement-441680293

Or You can simply use .then()

  useEffect(() => {
    asyncCall().then(setVal);
  });

Article on how to fetch - https://www.robinwieruch.de/react-hooks-fetch-data

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744400605a4572366.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信