so woon!

[STYLED COMPONENTS] Theme 버튼 페이지 header로 옮기기 본문

Styled Components/개념정리

[STYLED COMPONENTS] Theme 버튼 페이지 header로 옮기기

xowoony 2023. 4. 14. 15:51

학습일 : 2023. 04. 14


버튼의 위치를 header쪽으로 옮기고 싶기 때문에 App.tsx에서 버튼을 삭제해주고 Coins.tsx로 옮겨준다.
App에서 버튼을 지우게 되면 toggleDark function을 Coins로 보내주어야 한다.
근데 Coins는 Router 안에 있기 때문에
function을 Router로 보내주어야 한다.



<App.tsx>
변경 전

function App() {
  const [isDark, setIsDark] = useState(false);
  const toggleDark = () => setIsDark((current) => !current);
  return (
    <>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
        <GlobalStyle />
        <Router />
        <ReactQueryDevtools initialIsOpen={true} />
        <button onClick={toggleDark}>테마 변경</button>
      </ThemeProvider>
    </>
  );
}

export default App;



변경 후

function App() {
  const [isDark, setIsDark] = useState(false);
  const toggleDark = () => setIsDark((current) => !current);
  return (
    <>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
        <GlobalStyle />
        <Router toggleDark={toggleDark} />
        <ReactQueryDevtools initialIsOpen={true} />
      </ThemeProvider>
    </>
  );
}

export default App;



그런다음 Router.tsx 로 가서 인터페이스를 생성해야 한다
* Router가 function을 받도록 하고 싶을때는 function이 어떻게 생겼는지 명시해주어야 하는데
App.tsx에서 toggleDark를 hover 해보면 const toggleDark: () => void 이 뜸
(이 경우 function은 argument를 받지 않고 아무것도 리턴하지 않음)

<Router.tsx>
따라서 Router.tsx에 이 함수의 타입대로 적어줌.
Coins스크린에 toggleDark를 적어주고

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

interface IRouterProps {
  toggleDark: () => void;
}

function Router({ toggleDark }: IRouterProps) {
  return (
    <BrowserRouter basename={process.env.PUBLIC_URL}>
      <Routes>
        <Route path={`/`} element={<Coins toggleDark={toggleDark} />} />
        <Route path="/:coinId/*" element={<Coin />} />
      </Routes>
    </BrowserRouter>
  );
}
export default Router;




Coins.tsx
Coins.tsx 에도 인터페이스를 생성해준다.
그런 뒤 Coins function에 넘겨주고
그리고 버튼에 onClick={toggleDark} 를 작성해준다

interface ICoinsProps {
  toggleDark: () => void;
}

function Coins({toggleDark}:ICoinsProps) {
  // useQuery를 통해 Coins 를 fetch
  const { isLoading, data } = useQuery<ICoin[]>("allCoins", fetchCoins);
  return (
    <Container>
      <Helmet>
        <title>Thorn Coin</title>
      </Helmet>
      <Header>
        <Link to={"/"}>
          <Title>Thorn Coin</Title>
        </Link>
        <SubTitle>Grab Your Own Coin!</SubTitle>
        <button onClick={toggleDark}>테마 변경</button>
      </Header>
      {isLoading ? (
        <Loader>로딩중입니다...</Loader>
      ) : (
        <CoinsList>
          {data?.slice(0, 100).map((coin) => (
            <Coin key={coin.id}>
              <Link to={`/${coin.id}`} state={coin}>
                <Img
                  src={` https://cryptocurrencyliveprices.com/img/$ {coin.id}.png`}
                  alt=""
                />
                {coin.name}
              </Link>
            </Coin>
          ))}
        </CoinsList>
      )}
    </Container>
  );
}

export default Coins;





실행결과
그럼 Coins 페이지에서 헤더에 버튼이 들어왔고
클릭시에도 테마변경이 정상적으로 됨을 확인 할 수 있다.

 

Comments