1.6 React masterClass (CoinStore 마무리)

hun2__2·2022년 1월 6일
0

Have a fruitful vacation

목록 보기
10/24
post-thumbnail

이제 coin page에서 nesting router로 탭을 구현하고 그 안에서 chart를 보여줄 것이다.

먼저 Coins, Coin을 만들어준 것과 같이 coin.tsx안에 chart, price 라우터와 들어갈 수 있는 링크를 만들어준다.

여기서 신기함점이 백틱을 사용하지 않고 그냥 :coinId라고 해도 인식한다..! react-router덕분에 :뒤는 변수로 취급해서 :coinId뿐만아니라 :anything 이렇게 아무거나 넣어도 가능해진다.

react-router의 hook인 useRouteMatch을 사용해서 현재의 URL이 일치하는지 boolean 값으로 반환해주고

Tab component의 prop로 현재 URL을 받아와서 일치하면 theme의 색으로 바꿔준다.

이제 각각의 Tab을 누르면 chait와 price에 들어가진다.

이제 coin안에 router를 만들었으니 각각 componenet에 data를넣어줄 것이다.
먼저 chart.tsx에는 coin의 historical data가 들어갈 것인데 https://api.coinpaprika.com/v1/coins/{coin_id}/ohlcv/latest/
에서 data를 받아온다 여기서 넘겨주는 data는 와 같이 생긴 것으로 이 정보들로 chart를 꾸밀 것이다.

이전의 과정과 같이 api.ts에서 data를 fetch해주는 함수를 만들고
chart.tsx에서 useQuery를 사용해서 data를 사용할 것이다

먼저 이번에는 url 파라미터로 starttime, endtime을 넣어주어 데이터를 짤라서 받아올 것이다.

export function fetchCoinHistory(coinId: string) {
  const endDate = Math.floor(Date.now() / 1000);
  const startDate = endDate - 60 * 60 * 24 * 7 * 2;

  return fetch(
    `${BASE_URL}/coins/${coinId}/ohlcv/historical?start=${startDate}&end=${endDate}`
  ).then((res) => res.json());
}

이렇게 최근 2주의 data를 받아오고

넘겨 받는 data의 type을 지정해준뒤 useQuery를 사용해서 받아온다.

interface IHistoricalData {
  time_open: string;
  time_close: string;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
  market_cap: number;
}

function Chart({ coinId }: ChartProps) {
  const { isLoading, data } = useQuery<IHistoricalData[]>(
    ["ohlcv", coinId],
    () => fetchCoinHistory(coinId)
  );
  return (
    <div>
      {data?.map((price) => (
        <div>{price.close}</div>
      ))}
    </div>
  );
}

정보가 잘 넘어온다!

이제 apexcharts를 사용해서 chart를 그려줄것인데 공식문서를 보고 따라해보자
(참고 : https://apexcharts.com/docs/react-charts/)

❯ npm install --save react-apexcharts apexcharts     

를 입력해주고

import ApexChart from "react-apexcharts";

를 해주면 chart를 받아올 수 있다.

chart에는 여러가지 props가 필요한데 뭐가 있는지 궁금해서 ctrl+클릭을 해보니

이런 정보들을 넣을 수가 있다.
data가 들어가는 series에 우리 데이터인 data를 이용해서 종가를 넣어주고 그림의형태인 type으로는 line을 넣어주고

<ApexChart
	type="line"
	series={[
		{
			name: `${coinId}가격`,
			data: data?.map((price) => price.close),
		},
	]}

각종 옵션값들은 options에 넣어주니
(option값 참고: https://apexcharts.com/docs/options/)

이렇게 이쁘게 마무리 되었다!

이제 여기에 recoil을 사용하여 상태관리를 하며 다크모드, 라이트 모드가 가능하게 만들 것이다
recoil은 react에서 useContext를 이용해서 만든 상태관리 라이브러리로 redux처럼 상태관리를 편하게 해준다. recoil에서는 상태관리를 위해 여러 컴포넌트에서 필요한 state들을 Atom이라는 곳에 저장하고 사용한다. 사용법은 매우 간단했다!\
(참고 : https://recoiljs.org/ko/docs/introduction/getting-started)

먼저 install하고

yarn add recoil
yarn add @types/recoil

app.tsx에서 RecoilRoot로 감싸준다

그러면 이 안에 있는 곳에서 Atom에 저장한 state값을 사용할 수 있다.

먼저 Atom을 만드는 방법은

import { atom } from "recoil";

export const modeChange = atom({
  key: "isDark",
  default: true,
});

이렇게 만들어주고

Atom에 저장된 state를 사용하고 싶으면
useRecoilValue(Atom이름)을 사용해서 Atom안의 값을 가져오고

const isDark = useRecoilValue(modeChange);

Atom에 저장된 state를 변경하고 싶으면
useRecoilValue(Atom이름)을 사용해서 Atom안의 값을 변경시켜준다

const setMode = useSetRecoilState(modeChange)

여기서 받은 setMode는 Atom의 default값을 변경할 때 setState처럼 사용할 수 있다.

또한 Atom을 이용하여 useState처럼 사용하고 싶으면 useRecoilState(Atom이름)을 사용하면 된다

const [state, setState] = useRecoilState(modeChange)

근데 이렇게 하면 error가 난다 그 이유는 recoil의 내장 hook를 사용할 수 있는 곳은 RecoilRoot 내부 component에서만 가능하다. 따라서 App.tsx에서 감싸고있던 RecoilRoot을 index로 변경시켜준다.

// index.tsx
ReactDOM.render(
  <React.StrictMode>
    <RecoilRoot>
      <App />
    </RecoilRoot>
  </React.StrictMode>,
  document.getElementById("root")
);

// App.tsx
function App() {
  const mode = useRecoilValue(modeChange);
  return (
    <QueryClientProvider client={queryClient}>
      <ThemeProvider theme={mode ? darkTheme : lightTheme}>
        <GlobalStyle />
        <Router />
      </ThemeProvider>
      {/* //! 이걸 사용해서 캐시에 뭐가 저장되어있는지 확인 할 수 있다 */}
      <ReactQueryDevtools initialIsOpen={true} />
    </QueryClientProvider>
  );
}

이제 App.tsx를 포함한 내부 component들은 모드 recoil함수를 사용할 수 있다.

이제 바꿔야 하는 색상들에 mode로 삼항연산자를 만들어주면
ex) chart의 options ={theme: { mode: mode ? "dark" : "light" },}

두 가지 모드가 생성되었고 Atom의 default값만 변경하면 한번에 변경된다!!

이제 header에 버튼을 만들어서 useSetRecoilState(modeChange)로 atom의 default를 변경시켜준다.

app에 있는 mode값을 prop로 받고 useSetRecoilState를 사용해도 되지만
한번에 받아오고 변경할 수 있는 useRecoilState를 사용하면 더 편리하다

이제 뒤로가기 버튼과 남은 price차트를 꾸며볼 것이다.
이렇게 하면 마무리가 된다!!

뒤로가기 버튼과 모드를 변경해주는 버튼을 Header에 만들기로 정했다.
뒤로가기는 사실 그냥 coins으로 돌아가는거라

<Link to="/">Home</Link>

로 만들면 끝난다
cf) Link로 넘어가기 위해서는 BrowserRouter안에 있어야 하므로 Header comopent를 Roueter.tsx에서 BrowserRouter안에 넣어주었다.

그리고 모드 변경 버튼은 useRecoilState를 이용해서 현재 모드를 받아오고, 수정할 수 있다

//Header.tsx
function Header() {
  const [mode, setMode] = useRecoilState(modeChange);
  const toggleMode = () => setMode((prev) => !prev);

  return (
    <Container>
      <Btn>
        <Link to="/">Home</Link>
      </Btn>
      <Btn onClick={toggleMode}> {mode ? "다크모드" : "라이트모드"}</Btn>
    </Container>
  );
}
export default Header;

마지막으로 Price공간에 무엇을 넣을까 하다가 오늘 가격을 deTail하게 보여주기로 정했다.
chart는 를 참고 해서 만들었고

https://api.coinpaprika.com/#tag/Tickers/paths/~1tickers~1{coin_id}~1historical/get 에서 기간을 지금부터 24H 전까지로 잡고 data를 받아왔다.

완성!!!

gitHub : https://github.com/jae-hun-e/react-masterclass/tree/coin




배운 것을 토대로 주식api를 이용해서 candle chart를 만들고 내 웹에 추가해봐야겠다. TS + react-router + react-query + recoil 모두 사용해보면서 익혀나갈 것이다ㅎㅎ

ps.
react도 재밌고 JS도 재밌다 빨리 강의듣고 익힌다음 공식문서 보면서 내꺼 작업하고 싶다
근데 다음주에 파이썬 챌린지 시작이네... 강의를 이번주내에 빨리 끝내야겠다!

오늘부터 영어 스터디를 시작했다. 디스코드로 3분정도 영상과, 스크랩트, 5개문장을 데일리 미션으로 주신다. 몇번해보다가 괜찮은것 같으면 유료결재로 PDF도 받아봐야겠다!

해외인턴을 찾아보다가 ICT학점연계프로젝트인턴십 이라는것을 알게되었다.
(https://www.ictintern.or.kr/main.do)
올해는 글른것갔고... 지금부터 빡시게 영어, 다른 포폴들 준비해서 졸업하기전에 꼭 가자ㅜㅜㅜ 너무 가고싶다,,,

이번 방학동안에는 JS, TS, React, ReactNative 이것들을 원하는 것 만들 정도로만 실력이 늘면 좋겠다ㅎㅎ...

profile
과정을 적는 곳

0개의 댓글