[팀 프로젝트] 상태관리 및 성능 최적화 개선

Hyowmls·2024년 7월 31일
0
post-thumbnail
post-custom-banner

상태 관리 수정

전문가 의뢰 메인페이지에서 posts와 filteredPosts가 있는데 결론적으로는 filteredPosts만 사용하고 있었다. 같은 데이터를 두 개로 관리하면 실수를 할 가능성이 높아진다는 피드백을 받고 기존 코드를 수정해서 filteredPosts만 상태관리를 하도록 수정했다.

  • 기존 posts와 filteredPosts가 있음 ( 같은 데이터 )
  • filteredPosts만 상태 관리하도록 수정

기존 코드

  • fetchData() 비동기 함수로 특정 페이지와 언이 필터링 조건에 따라 데이터를 가져옴
    langQuery : 선택된 언어가 있으면 쿼리 문자열에 추가
    url : 데이터를 가져올 API 엔드포인트
    response & data : 데이터를 가져와 JSON 형식으로 파싱
  • 데이터를 가져와 posts와 filteredPosts 상태를 업데이트
  • page 또는 selectedLanguages가 변경될 때 마다 fetchData() 함수를 호출하여 데이터를 다시 가져옴
  • selectedLanguages또는 posts가 변경될 때 마다 필터링된 게시물 리스트를 업데이트함
    선택된 언어가 있을 경우, 해당 언어에 맞는 게시물만 필터링하여 filteredPosts 상태를 업데이트함
    선택된 언어가 없을 경우, 전체 게시물을 filteredPosts에 저장함
  • 사용자가 페이지를 스크롤하여 거의 끝에 도달했을때, 다음 페이지의 데이터를 로드함 ( 무한 스크롤 )
  • handleScroll 함수가 스크롤 이벤트를 감지하고 조건이 맞으면 페이지 번호를 증가시킴
  • handleLanguageFilter 함수는 선택된 언어를 업데이트하고, 해당 언어로 데이터를 다시 로드함
    선택된 언어가 이미 리스트에 있는 경우, 리스트에서 제거
    선택된 언어가 리스트에 없는 경우, 리스트에 추가
    페이지 번호를 0으로 리셋하고, 새로 선택된 언어에 맞게 데이터를 다시 가져옴

수정 코드

  • 데이터를 불러와서 상태를 업데이트 하는 방식은 동일하지만 filteredPosts 의 상태만 업데이트함
  • 사용자가 페이지를 스크롤하여 거의 끝에 도달했을때 loading 상태를 true 로 변경
  • loading 상태가 true 로 변경되었을때 데이터를 가져오는 로직을 처리함
  • handleLanguageFilter 함수는 선택된 언어를 업데이트하고, 해당 언어로 데이터를 다시 로드함

성능 최적화

기존 코드에서 fetchData() 가 컴포넌트가 렌더링 될 때 마다 새로 생성되고 있었다. 성능 최적화를 위해 useEffect내부 또는 컴포넌트 외부에 선언하는것이 좋다고 피드백을 받아서 개선했다

기존 코드

  const fetchData = async (page: number, languages: string[] = []) => {
    try {
      const langQuery = languages.length > 0 ? `&languages=${encodeURIComponent(JSON.stringify(languages))}` : '';
      const url = `/api/proMain?page=${page}${langQuery}`;
      const response = await fetch(url);
      const data = await response.json();

      if (data && Array.isArray(data)) {
        if (page === 0) {
          setFilteredPosts(data);
        } else {
          setFilteredPosts((prevPosts) => [...prevPosts, ...data]);
        }
      } else {
        console.error('data fetch error');
      }
    } catch (error) {
      console.error(error);
    }
  };

피드백을 받고 useEffect 내부에서 선언을 하려고 했는데 그럴 경우 코드의 재사용성이 낮아질 수 있을것 같다는 생각을 했다.
그래서 fetchData 함수를 useCallback() 함수로 감싸 주기로 결정을 했다

수정 코드

  const fetchData = useCallback(async (page: number, languages: string[] = []) => {
    try {
      const langQuery = languages.length > 0 ? `&languages=${encodeURIComponent(JSON.stringify(languages))}` : '';
      const url = `/api/proMain?page=${page}${langQuery}`;
      const response = await fetch(url);
      const data = await response.json();

      if (data && Array.isArray(data)) {
        if (page === 0) {
          setFilteredPosts(data);
        } else {
          setFilteredPosts((prevPosts) => [...prevPosts, ...data]);
        }
      } else {
        console.error('data fetch error');
      }
    } catch (error) {
      console.error(error);
    }
  }, []);
post-custom-banner

0개의 댓글