React - Harry Potter 기숙사 소개 페이지 제작 (Day 2)

조민수·2024년 1월 30일
0

개발

목록 보기
2/9

진행 단계, 리팩토링

1. api > getData.ts

  • Data fetching의 불안정성과 비동기성으로
    try-catch 형태로 리팩토링했다.
  • 각 기숙사별 데이터를 가져오는데 name field가 필요한 줄 알았는데 id field가 필요했다.
    -> id와 name을 함께 가져오는 걸로 리팩토링했다.
import axios from "axios";
import { GetNameAndId } from "../model/house";

const data = axios.create({
  baseURL: "https://wizard-world-api.herokuapp.com",
});

export const getHouse = async () => {
  const response = await data.get("/Houses");
  return response.data;
};

export const getHouseName = async () => {
  try {
    const response = await data.get("/Houses");
    return response.data.map((item: GetNameAndId) => ({
      id: item.id,
      name: item.name,
    }));
  } catch (err) {
    console.log(err);
    return [];
  }
};

// id 통해서 해당 기숙사 정보 가져오기

export const getHouseById = async (id: string) => {
  try {
    const response = await data.get(`/Houses/${id}`);
    return response.data;
  } catch (err) {
    console.log(err);
  }
};

2. model > house.ts

  • 기존의 HouseData에서 id와 name Attributes들로만 구성된 GetNameAndId type을 추가했다.
export type GetNameAndId = Pick<HouseData, "id" | "name">;

3. App.tsx

  • Routes를 구성했다.
const App: React.FC = () => {
  return (
    <div className="App">
      <QueryClientProvider client={queryClient}>
        <Header />
        <Routes>
          <Route path="/" element={<MainPage />} />
          <Route path="/house/:houseID" element={<House />} />
        </Routes>
        <Footer />
      </QueryClientProvider>
    </div>
  );
};

4. pages > MainPage.tsx

  • useEffect 방식의 data 비동기성 처리를 제거하고
    react query의 data fetching 만으로의 코드로 리팩토링했다.
  • 만들고 코드를 보다보니 도대체 내가 왜 어제 useEffect를 넣었을까? 의구심이...
export const MainPage: React.FC = () => {
  const navigate = useNavigate();
  const {
    data = [],
    isLoading,
    error,
  } = useQuery<GetNameAndId[]>(["house"], () => getHouseName());

  if (isLoading) return <div>now in Loading...</div>;
  if (error) return <div>ERROR OCCURED</div>;
  
  return (
    <StyledDiv>
      <h2>Choose Your House</h2>
      <HouseGrid>
        {data.map((item) => {
          return (
            <div key={item.id} onClick={() => navigate(`/house/${item.id}`)}>
              <ImgHandler name={item.name} height="130px" />
              <p>{item.name}</p>
            </div>
          );
        })}
      </HouseGrid>
    </StyledDiv>
  );
};

5. pages > House.tsx

  • useParams를 통해 houseID값을 받아오고
    이를 react query의 key로 지정해, 해당 값의 변경이 있으면 다시 data를 fetching 하는 형태의 로직을 구성했다.
export const House: React.FC = () => {
  const { houseID } = useParams();

  const { data, isLoading, error } = useQuery<HouseData>(
    ["houseDetail", houseID],
    () => getHouseById(houseID!),
    {
      enabled: !!houseID, // houseID가 있을 때만 쿼리 실행
    }
  );
  if (isLoading) return <div>now in Loading...</div>;
  if (error) return <div>ERROR OCCURED</div>;

  if (data) {
    return ( ... ) 
  }

추후 진행 단계

  1. House.tsx 페이지 내 애니메이션 구현
  2. House.tsx 페이지 세부 컴포넌트 리팩토링
  3. MainPage.tsx component hover, click 애니메이션
  4. Header에서 선택한 기숙사 값 css -> 상태관리 recoil -> House.tsx 값 변경 과정 리팩토링
  5. Responsive UI 적용
profile
사람을 좋아하는 Front-End 개발자

0개의 댓글