React TS 기반 짤막한 프로젝트를 하고 싶었다.
쓸만한 API가 없나 찾아보다가
https://wizard-world-api.herokuapp.com/swagger/index.html 에서 해리포터 관련된 다양한 API를 get형태로 제공하는 것을 찾았다.
그 중에서
를 사용하기로 했고, 프로젝트 사이즈를 키워보고 한다면 Spells나 Wizards 까지 써봐도 괜찮을 듯 싶다.
까지는 사실상 필수였고
추가적으로 이번 프로젝트를 통해 가져갈 스킬은
정도가 되겠다.
로 구성하였다.
( 어떤 방식이 현업에서 쓰이고, 가장 효율적인지는 배워가며 적용해봐야 알 듯... )
House의 전체적인 정보와
House의 이름만 필요한 경우가 있어서 이를 구분해 함수를 만들었다.
import axios from "axios";
import { House } 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 () => {
const response = await data.get("/Houses");
return response.data.map((item: House) => item.name);
};
// id 통해서 해당 기숙사 정보 가져오기
export const getHouseById = async (id: string) => {
const response = await data.get(`/Houses/${id}`);
return response.data;
};
getHouse를 통해 받아오는 response.data의 타입이
House[] 형식으로 올 수 있게끔 만들어놓았다.
export interface House {
animal: string;
commonRoom: string;
element: string;
founder: string;
ghost: string;
heads: Head[];
houseColours: string;
id: string;
name: string;
traits: Trait[];
}
export type Head = {
id: string;
firstName: string;
lastName: string;
};
export type Trait = {
id: string;
name: string;
};
import React, { useEffect, useState } from "react";
import { getHouseName } from "../api/getData";
import { useQuery } from "react-query";
import styled from "styled-components";
import { ImgHandler } from "../Components/ImgHandler";
export const MainPage: React.FC = () => {
const [nameArray, setNameArray] = useState<string[]>([]);
const { data, isLoading, error } = useQuery<string[]>(["house"], () =>
getHouseName()
);
useEffect(() => {
if (data) {
setNameArray(data);
}
}, [data]);
if (isLoading) return <div>now in Loading...</div>;
if (error) return <div>ERROR OCCURED</div>;
return (
<StyledDiv>
<h2>Choose Your House</h2>
<HouseGrid>
{nameArray.map((name) => {
return (
<div key={name}>
<ImgHandler name={name} height="130px" />
<p>{name}</p>
</div>
);
})}
</HouseGrid>
</StyledDiv>
);
};
const StyledDiv = styled.div`
display: flex;
flex-flow: column nowrap;
gap: 5vh;
padding: 10px;
align-items: center;
justify-content: center;
position: relative;
height: 70vh;
& > h2 {
font-family: "SOGANGUNIVERSITYTTF";
font-weight: 500;
color: #acacac;
}
`;
const HouseGrid = styled.div`
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: 2vw;
width: 95%;
& > div {
width: 100%;
border: 1px solid #787878;
border-radius: 15px;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
gap: 3vh;
cursor: pointer;
padding: 3vh 0;
& > p {
font-family: "SOGANGUNIVERSITYTTF";
font-size: 1.1rem;
margin: 0 !important;
}
}
`;
Components는 추후에 Components들로만 따로 작성할 예정