CRYPTO TRACKER 4.2 _ Home part One

Eugenius1st·2022년 3월 11일
0

ReactJS_MasterClass

목록 보기
19/48
post-custom-banner


hover 되면 색상 변경됨
클릭하면 link통해 다른 페이지로 이동됨

Router

import { BrowserRouter, Switch, Route } from "react-router-dom";
import Coin from "./routes/Coin";
import Coins from "./routes/Coins";

function Router() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/:coinId">
          {/* Router에게 URL이 변수값을 갖는 것을 말해주는 방식이다
          이제 할일은 coinId를 잡아내는 일이다. URL의 파라미터 부분을 잡아내고 싶을 때
          useParams 훅을 사용하기만 하면 된다.*/}
          <Coin />
        </Route>
        <Route path="/">
          <Coins />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}
export default Router;

route/Coin

import { useParams } from "react-router";
//useParams 는 URL에서 관심있어 하는 정보를 잡아낼 수 있게 해준다.
interface RouteParams {
  coinId: string;
}

function Coin() {
  const { coinId } = useParams<RouteParams>();
  // coinId가 string 이라는 것을 말해줄 수 있고
  // const{ coinId } = useParams<{coinId:string}>(); 이렇게
  //또는
  //타입스크립트에게 Params 라는 이름의 interface를 갖는다는 것을 말해 줄 수 있다.
  // interface Params{coinId:string;}
  // const{ coinId } = useParams<Params>();

  return <h1>Coin : {coinId}</h1>;
}

export default Coin;

route/Coins

import styled from "styled-components";
import { Link } from "react-router-dom";

const Container = styled.div`
  padding: 0px 20px;
`;

const Header = styled.header`
  height: 10vh;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const CoinsList = styled.ul``;

const Coin = styled.li`
  background-color: white;
  color: ${(props) => props.theme.bgColor};
  margin-bottom: 10px;
  padding: 20px;
  border-radius: 15px;

  a {
    padding: 20px; // 좀 더 넓은 범위에서 transition 효과 적용 가능
    transition: color 0.2s ease-in;
    display: block; //화살표 범위 이상 클릭해도 transition 효과 적용 되도록
  }

  &:hover {
    a {
      color: ${(props) => props.theme.accentColor};
    }
    // 아래에서는 a가 아닌 Link라는 이름으로 사용했지만
    // css에서는 anchor 를 선택해야 했다. 이건 모든 react router link들이
    // 결국에는 anchor로 바뀔거기도 하고,
    // react router dom이 우리 대신 설정을 도와줄 특별한 event listener들이 있기도 하다
  }
`;

const Title = styled.h1`
  font-size: 48px;
  color: ${(props) => props.theme.accentColor};
`;

const coins = [
  {
    id: "btc-bitcoin",
    name: "Bitcoin",
    symbol: "BTC",
    rank: 1,
    is_new: false,
    is_active: true,
    type: "coin",
  },
  {
    id: "eth-ethereum",
    name: "Ethereum",
    symbol: "ETH",
    rank: 2,
    is_new: false,
    is_active: true,
    type: "coin",
  },
  {
    id: "usdt-tether",
    name: "Tether",
    symbol: "USDT",
    rank: 3,
    is_new: false,
    is_active: true,
    type: "token",
  },
];

function Coins() {
  return (
    <Container>
      <Header>
        <Title>코인</Title>
      </Header>
      {coins.map((coin) => (
        <Coin key={coin.id}>
          <Link to={`/${coin.id}`}>{coin.name} &rarr;</Link>
        </Coin>
      ))}
    </Container>
  );
}

export default Coins;

App

import { createGlobalStyle } from "styled-components";
import Router from "./Router";

export default function App() {
  const GlobalStyle = createGlobalStyle`
  @import url('https://fonts.googleapis.com/css2?family=Archivo+Narrow:wght@500&family=Bebas+Neue&family=Black+Han+Sans&family=Do+Hyeon&family=Source+Sans+Pro:wght@300;400&family=Ubuntu+Mono:ital@1&display=swap');
  html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, menu, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
main, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, menu, nav, section {
  display: block;
}
/* HTML5 hidden-attribute fix for newer browsers */
*[hidden] {
    display: none;
}
body {
  line-height: 1;
}
menu, ol, ul, li {
  list-style: none;

}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
*{
  box-sizing: border-box;
}
body{
  font-family: 'Source Sans Pro', sans-serif;
  //현재 App은 Theme안에 있으므로 Theme의 props에 접근 가능한 상태이다.
  //그 말은 즉슨 이렇게 쓸 수 있다는 뜻이다
  background-color: ${(props) => props.theme.bgColor};
  color : ${(props) => props.theme.textColor};
}
a{
  text-decoration: none;
  color:inherit;
// 링크가 클릭되었을 때 너무 못생겨져서 부모로부터 상속받게 하여
// 색깔을 유지시켰다
}
  `;
  return (
    <>
      <GlobalStyle />
      {/* 이것이 reset이고 기본값을 제거하는 방법이다. */}

      <Router />
    </>
  );
}

Index

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { ThemeProvider } from "styled-components";
import { theme } from "./theme";

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);
profile
최강 프론트엔드 개발자가 되고싶은 안유진 입니다
post-custom-banner

0개의 댓글