본문 바로가기

FE/React

useState가 의도대로 동작을 하지 않는다.

기존 코드

다음은 showTradeList 함수가 currentPage 상태를 기반으로 API 요청을 보내는 코드

const showTradeList = async () => {
    if (loading || currentPage > allPageCount) { return; }
    setLoading(true);

    const formData = new FormData();
    formData.append("page_num", currentPage.toString());

    await apiService.post<ApiResponse>(
      "/posts/search_second_hand/", formData,
    ).then(res => {
      if (res.data.code === 200) {
        const data = res.data.posts;
        setTradeList(pre => [...pre, ...data]);
        setAllPageCount(res.data.all_page_num);
        setCurrentPage(pre => pre + 1);
        setLoading(false);
      }
    });
};

clickShowMore 함수를 실행하면 currentPage를 1로 초기화하고 데이터를 다시 불러오도록 설계

const clickShowMore = () => {
    setMode("showMore");
    setCurrentPage(1);
    setAllPageCount(1);
    setTradeList([]);
    showTradeList();
};
 
 
문제점
  • setCurrentPage(1) 실행 후 바로 showTradeList가 호출되지만, 이 시점에서 currentPage 값이 아직 업데이트되지 않음
  • 이는 React의 상태 업데이트가 즉시 반영되지 않고, 다음 렌더링 주기에 반영되기 때문
  • 그 결과, showTradeList 함수 내에서 참조하는 currentPage 값이 여전히 이전 값을 유지하고 있어, API 요청이 잘못된 페이지 번호로 실행

 

해결 방법 1: useRef 활용

const currentPage = useRef<number>(1); // useRef 사용

const showTradeList = async () => {
    if (loading || currentPage.current > allPageCount) { return; } // 변경된 부분
    setLoading(true);
    const token = Cookies.get("token") || "";
    const apiService = new ApiService();
    const formData = new FormData();

    formData.append("page_num", currentPage.current.toString()); // 변경된 부분

    await apiService.post<ApiResponse>(
      "/posts/search_second_hand/",
      formData,
      token || undefined
    ).then(res => {
      if (res.data.code === 200) {
        const data = res.data.posts;
        setTradeList(pre => [...pre, ...data]);
        setAllPageCount(res.data.all_page_num);
        currentPage.current += 1; // 변경된 부분
        setLoading(false);
      }
    });
};

const clickShowMore = () => {
    setMode("showMore");
    currentPage.current = 1; // 변경된 부분
    setAllPageCount(1);
    setTradeList([]);
    showTradeList();
};

 

해결 방법 2: useEffect 제대로 사용하기

useEffect(() => {
  if (mode === "showMore" && currentPage === 1) {
    showTradeList();
  }
}, [currentPage, mode]);

const clickShowMore = () => {
    setMode("showMore");
    setCurrentPage(1);
    setAllPageCount(1);
    setTradeList([]);
    // showTradeList()를 여기서 직접 호출하지 않음
};

이 방식은 currentPage가 1이 되고 mode가 "showMore"일 때 showTradeList를 호출하도록 설정

'FE > React' 카테고리의 다른 글

React 컴포넌트 생명주기 (Lifecycle)  (0) 2025.05.18
Tailwind CSS vs Styled Components  (0) 2025.03.02
React useRef vs useState  (0) 2025.02.13
react-hook-form, register 렌더링 분석  (0) 2025.01.19
Recoil 메모리 누수 확인하기  (1) 2025.01.11