React, Typescript
도전과제 세계부자 리스트 API 받아와서 웹페이지 구성
himzei
2022. 9. 16. 20:22


동영상 강의를 들으면 늘 이해는 가는데 막상 코드챌린지를 해서 과제가 나오면 막막해진다.
다시 동영상을 보고 나도 비쥬얼 코드만 켜면 마찬가지다.
이번에는 무작정 코드 짜보고 모르는건 구글링으로 도전과제의 의도와는 관계없이 화면 구현에만 집중했다.
오늘이 첫 포스팅이지만
앞으로 얼마나 포스팅할 수 있을지 의문이다.
우선 폴더구조는 pages 아래에 about, index, globalStyle 파일을 줬다.

강의에서는 Tailwindcss를 배웠지만 주어진 블루프린트에서는 세팅을 하고 구글링을 해도 잘 몰라서
npm i styled-components를 활용했다.
아무래도 Tailwindcss 세팅 후 index.js에서 불러올 때 오류가 나는데 나중에 모법답안 올라오면 확인해 보려한다.
package.json 파일은 아래와 같다.
{
"name": "nextjs-blueprint",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"post-update": "yarn upgrade --latest"
},
"dependencies": {
"autoprefixer": "^10.4.11",
"next": "latest",
"postcss-cli": "^10.0.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-router-dom": "^6.4.0",
"styled-components": "^5.3.5"
},
"license": "MIT",
"keywords": [],
"description": "",
"devDependencies": {
"prettier": "^2.7.1",
"prettier-plugin-tailwindcss": "^0.1.13",
"tailwindcss": "^3.1.8"
}
}
크게 index와 about 페이지가 있는데
api 주소를 통해 데이터를 받아오는 부분은 fetch를 이용해서 받아왔는데 이부분도 강의를 다 보지 않아서 모르겠지만 다른방법이 있을 것 같고, 각각의 세계부자를 클릭 했을때 id 값을 넘겨줄때 useRouter를 이용해 push 해주었다. 이부분도 구글링 해서 찾아낸거지만 아무래도 강의에서는 다를 것 같다. 모법 답안이 기대된다.
index.js
import { useRouter } from "next/router";
import { useState } from "react";
import styled from "styled-components";
import GlobalStyle from "./globalStyle";
const Container = styled.div`
margin: 40px 0;
`;
const Inner = styled.div`
width: 1000px;
margin: auto;
display: grid;
grid-template-columns: repeat(4, 1fr);
row-gap: 30px;
column-gap: 5px;
`;
const FlexBox = styled.div`
display: flex;
flex-direction: column;
`;
const ImgBox = styled.img`
width: 200px;
height: auto;
margin-bottom: 5px;
`;
const TitleBox = styled.span`
font-weight: bold;
`;
const DetailBox = styled.span`
font-size: 12px;
`;
function IndexPage() {
const [data, setData] = useState([]);
const router = useRouter();
fetch("https://billions-api.nomadcoders.workers.dev/")
.then((response) => {
return response.json();
})
.then((item) => {
setData(item);
});
return (
<>
<GlobalStyle />
<Container>
<Inner>
{data?.map((item) => (
<FlexBox
key={item.id}
onClick={() =>
router.push({ pathname: "/about", query: { pid: item.id } })
}
>
<ImgBox src={item.squareImage} />
<TitleBox>{item.name}</TitleBox>
<DetailBox>{item.industries[0]}</DetailBox>
</FlexBox>
))}
</Inner>
</Container>
</>
);
}
export default IndexPage;
about.js
import GlobalStyle from "./globalStyle";
import { useRouter } from "next/router";
import { useState } from "react";
import styled from "styled-components";
const Container = styled.div`
margin: 40px 0;
`;
const Inner = styled.div`
width: 1000px;
background-color: #3f72af;
padding: 60px 20px;
margin: auto;
`;
const Contents = styled.div`
margin: 80px 0;
width: 100%;
height: 100%;
`;
const Wrap = styled.div`
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
`;
const ImgBox = styled.img`
width: 280px;
height: 280px;
margin-bottom: 10px;
`;
const TitleBox = styled.div`
font-size: 20px;
color: #f9f7f7;
`;
const ContentBox = styled.div`
width: 100%;
`;
const TitleBox2 = styled.h2`
font-size: 30px;
`;
const Grid = styled.div`
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
`;
const GridWrap = styled.div`
display: flex;
flex-direction: column;
border: 1px solid #dbe2ef;
padding: 10px;
`;
export default function AboutPage() {
const router = useRouter();
const pid = router.query.pid;
const [data, setData] = useState([]);
fetch(`https://billions-api.nomadcoders.workers.dev/person/${pid}`)
.then((response) => {
return response.json();
})
.then((item) => {
setData(item);
});
return (
<>
<GlobalStyle />
<Container>
<Contents>
<Inner>
<Wrap>
<ImgBox src={data.squareImage} />
<TitleBox>{data.name}</TitleBox>
<ContentBox>
Networth : {Math.round(data.netWorth)} millions
</ContentBox>
<ContentBox>Country : {data.country}</ContentBox>
<ContentBox>Industry : {data.industries}</ContentBox>
<ContentBox>{data.bio}</ContentBox>
</Wrap>
</Inner>
</Contents>
<Contents>
<Inner>
<Wrap>
<TitleBox2>Financial Assets</TitleBox2>
<Grid>
{data?.financialAssets?.map((item, index) => (
<GridWrap>
<ContentBox>{item.ticker}</ContentBox>
<ContentBox>{item.companyName}</ContentBox>
<ContentBox>{item.currentPrice}</ContentBox>
</GridWrap>
))}
</Grid>
</Wrap>
</Inner>
</Contents>
</Container>
</>
);
}