오늘도 비동기와의 싸움

Wynter24·2023년 9월 25일
0

처음 작성한 코드

⚒️구현하고자 한 기능

slider를 클릭했을 때 getCityBookMark 함수가 실행되고 city관련 데이터를 불러와 화면에 나타낸다.

🚨문제

slider를 클릭했을 때 getBookMark 함수로 가져온 데이터가 먼저 보이고 한번더 클릭해야 getCityBookMark함수가 가져온 데이터가 보인다.

 const getBookMark = async () => {
    try {
      const response = await baseInstance.get('bookmark', {
        headers: { Authorization: `${localStorage.getItem('Authorization')}` },
      });
      console.log('BookMark response', response);
      // API 응답 데이터를 배열에 저장
      setBookmarkData(response.data.bookmarkList);
      setCities(response.data.cityList);
    } catch (error) {
      console.log(error);
    }
  };
 
 useEffect(() => {
    getBookMark(); getCityBookMark(); console.log("렌더링 됨")
  }, [city]);
  
  return(<SliderArea>
          <Slider texts={cities} setCity={setCity} getCityBookMark={getCityBookMark}/>
        </SliderArea>)

수정

원인😂

useEffect 훅에서 getBookMark()와 getCityBookMark()를 동시에 호출하면 두 함수가 병렬로 실행되어 비동기적으로 동작할 수 있다. 이 경우, 두 함수의 실행 순서를 보장할 수 없고, 원하는 결과를 얻을 수 없다.

원하는 동작을 얻기 위해서는 getBookMark()가 완료된 후에 getCityBookMark()를 실행하도록 조정해야 한다. 이를 위해 getBookMark()를 호출하는 useEffect와 getCityBookMark()를 호출하는 useEffect를 분리하고, getCityBookMark()를 getBookMark()의 콜백 함수로 실행하면 된다.

const getBookMark = async () => {
    try {
      const response = await baseInstance.get('bookmark', {
        headers: { Authorization: `${localStorage.getItem('Authorization')}` },
      });
      console.log('BookMark response', response);
      // API 응답 데이터를 배열에 저장
      setBookmarkData(response.data.bookmarkList);
      setCities(response.data.cityList);
      getCityBookMark(); // 추가
    } catch (error) {
      console.log(error);
    }
  };

 useEffect(() => {
    getBookMark(); console.log("렌더링 됨")
  }, [city]);

return(<SliderArea>
          <Slider texts={cities} setCity={setCity} getCityBookMark={getCityBookMark}/>
        </SliderArea>)

city 상태가 업데이트되면 해당 useEffect가 재실행되고 getBookMark 함수가 호출된다. 그런 다음 getCityBookMark가 호출되므로 city에 따라 데이터가 다시 불러와진다.

먼저 city가 변경되면 useEffect 내부에서 getBookMark가 호출되고 getBookMark 내에서 getCityBookMark가 호출된다. 따라서 getCityBookMark가 호출되기 전에 getBookMark가 호출되므로, 먼저 전체 북마크 데이터가 불러와진다.

그런 다음 getCityBookMark가 호출되어 지정된 city에 해당하는 북마크 데이터만 다시 불러와진다. 이렇게하면 city가 업데이트될 때마다 해당 도시의 북마크 데이터가 업데이트되어 List에 표시된다.

요약하면, getBookMark가 전체 북마크 데이터를 불러오고, 이후 getCityBookMark가 특정 도시의 북마크 데이터를 다시 불러온다.

profile
내가 다시 보려고 쓰는 개발.log

0개의 댓글

관련 채용 정보