[알라북스] QA 렌더링 해결

XCC629·2022년 6월 13일
0

에러해결

목록 보기
2/2

알라북스

배포주소: http://13.209.81.196:3000/

백 개발자에게 1차개발 QA를 부탁했습니다. 자잘한 문제들은 쉽게 처리했지만, 아래 두 문제는 해결 과정을 남기는 것이 좋을 것 같아 정리합니다.

이슈

  • 새로고침했을때도 렌더링 주소 그대로임
  • 어떤 카테고리에서 책 상세페이지에 들어갔다가 뒤로가기하면 무조건 로맨스 카테로 이동하네요

다른 것처럼 보이지만 사실 같은 기능의 문제입니다.

문제발생 이유

카테고리 클릭할 때 스타일이 변경되는 부분과 라우터를 컨트롤 하는 변수와 함수가 분리되어 있었습니다.


export default function MainDelay() {
  const [isLoading, setIsLoading] = useState(true);
  const [bookData, setBookData] = useState(null);
  const [categoryName, setCategoryName] = useState("romance");

//fetch 부분 catergortName에 의존
  useEffect(() => {
    getBookCategory(categoryName)
      .then((data) => {
        setBookData(data);
        return data.length;
      })
      .then((isComplete) => isComplete && setIsLoading(false));
  }, [categoryName]);


  return isLoading ? (
    <Loading />
  ) : (
    <Main setCategoryName={setCategoryName} bookData={bookData} />
  );
}


function Main({ setCategoryName, bookData }) {
  const navigator = useNavigate();
  // 스타일 정하는 상태
  const [click, setClick] = useState([true, false, false, false]);
  
  //클릭 시 스타일 변경 및 카테고리 설정
  const onClickCategory = (category, index) => {
    setClick(() => {
      const newArr = Array(4).fill(false);
      newArr[index] = !newArr[index];
      return newArr;
    });
    navigator(`/books?category=${category}`);
    setCategoryName(category);
  };
  
  const onClickBook = (id) => {
    navigator(`/books/${id}`);
  };
  
  return (
    <div style={{ position: "relative" }}>
      <CategoryNav onClickCategory={onClickCategory} click={click} />
      <BannerSlide bookData={bookData} />
      <NowBookList bookData={bookData} onClickBook={onClickBook} />
    </div>
  );
}

해결 방안 고민

따라서 한 가지 변수에 기대게 하는 것이 옳다고 생각하였고, 그 기준을 라우터 주소로 잡았습니다.
라우터 주소로 잡은 이유는 뒤로가기, 새로고침 시 라우터 주소는 잘 유지되기 때문이었습니다.

두번째로, 어차피 첫 렌더링 때 한 개의 카테고리 페이지를 보여주니 초기 라우터 값을 로맨스로 고정하였습니다.

코드 변경

export default function MainDelay() {
  const { search } = useLocation(); //라우터 주소 가져오기
  
  // 라우터 주소에서 카테고리 부분만 빼서 스티링을 리턴하는 함수
  const selectCategorySearch = () => {
    let index = search.indexOf("=");
    let category = search.slice(index + 1);
    return category;
  };

  const [isLoading, setIsLoading] = useState(true);
  const [bookData, setBookData] = useState(null);
  //라우터에 따라 상태가 달라진다
  const [categoryName, setCategoryName] = useState(selectCategorySearch());

//라우터가 바뀔때마다 상태도 변경시켜주도록 
  useEffect(() => {
    setCategoryName(selectCategorySearch());
  }, [search]);
  
//비동기처리 및 에러 핸들링
  useEffect(() => {
    const renderCategory = async () => {
      try {
        const data = await getBookCategory(categoryName);

        if (data.message) throw new Error(data.message);

        setBookData(data);
        setIsLoading(false);
      } catch (err) {
        console.log(err);
      }
    };
    renderCategory();
  }, [categoryName]);

  return isLoading ? (
    <Loading />
  ) : (
    <Main
      categoryName={categoryName}
      setCategoryName={setCategoryName}
      bookData={bookData}
    />
  );
}

function Main({ categoryName, setCategoryName, bookData }) {
  const navigator = useNavigate();

// 카테고리 클릭시 라우터 이동
  const onClickCategory = (category) => {
    navigator(`/books?category=${category}`);
  };

  const onClickBook = (id) => {
    navigator(`/books/${id}`);
  };

  return (
    <div style={{ position: "relative" }}>
      <CategoryNav
        onClickCategory={onClickCategory}
        categoryName={categoryName}
      />
      <BannerSlide bookData={bookData} />
      <NowBookList bookData={bookData} onClickBook={onClickBook} />
    </div>
  );
}

이렇게 하여서 라우터가 바뀌는 것에 의존하게 되었다. 흐름도 깔끔하고, 카테고리가 추가되었을때 수정 전 코드는 click state를 변경해줘야하는 것에 비해 이 코드는 그럴 필요가 없다. 재사용성이 높아졌다!

흐름정리

profile
프론트엔드 개발자

0개의 댓글