본문 바로가기

코딩/Today I Learn

React Js Master #1styled components ,themes

728x90

프로젝트 셋업

 

1.

npx create-react-app react-masterclass

 

2.

초기화: 필요 없는 파일과 import 지우기

 

 

 

styled components

 

1. npm i styled-components

2. npm start 

 

 

import "./App.css";
import styled from "styled-components";

const Father = styled.div`  styled.태그`백틱 안에 css코드`
    display: flex;
`;
const Box1 = styled.div`
    background-color: teal;
    width: 100px;
    height: 100px;
`;
const Box2 = styled.div`
    background-color: tomato;
    width: 100px;
    height: 100px;
`;
const Text = styled.text`
    color: white;
`;
function App() {
    return (   //구현 부분이 매우 깔끔해진 것을 알 수 있다.
        <Father>
            <Box1>
                <Text>Hello</Text>
            </Box1>
            <Box2 />
        </Father>
    );
}

export default App;

 

 

styled component css 적용 시 자동완성은
vscode-styled-components 익스텐션을 받으면 되네요

 

컴포넌트 설정


const Box = styled.div`
    background-color: ${(props) => props.bgColor};
    width: 100px;
    height: 100px;
`;

function App() {
    return (
        <Father>
            <Box bgColor="teal" />
            <Box bgColor="tomato" />
        </Father>
    );
}

컴포넌트 확장


const Box = styled.div`
    background-color: ${(props) => props.bgColor};
    width: 100px;
    height: 100px;
`;

const Circle styled(Box)`
    border-radius: 50px;
`;
function App() {
    return (
        <Father>
            <Box bgColor="teal" />
            <Circle bgColor="tomato" />
        </Father>
    );
}

export default App;

컴포넌트 Html 엘리먼트 바꾸기 as

 

const Box = styled.button` 해당 부분! 엘리먼트만 바꾸고 css는 그대로 사용하고 싶을 때
    background: red;
    width: 100px;
    height: 100px;
`;

function App() {
    return (
        <Father>
            <Box>Log in</Box>
            <Box as="a" href="/">
                Log in
            </Box>
        </Father>
    );
}

 

컴포넌트 속성 일괄 입력 attrs

 


const Input = styled.input.attrs({ required: true, minLength: 10 })`
    background: tomato;
`;

function App() {
    return (
        <Father>
            <Input />
            <Input />
            <Input />
            <Input />
        </Father>
    );
}

 

위와 같이 입력함으로써

return (
        <Father>
            <Input required/>
            <Input required/>
            <Input required/>
            <Input required/>
        </Father>
    );

처럼 미련하게 복붙으로 작업하지 않아도 된다.


styled component에서 애니메이션 주는 법 

import styled,{keyframes} from "styled-component"

 

const rotateAnimation = keyframes`
    from{
        transform: rotate(0deg);
    }to{
        transform: rotate(360deg);
    }
`;
const Box = styled.div`
    height: 200px;
    width: 200px;
    background-color: tomato;
    animation: ${rotateAnimation} 1s linear infinite;

 

스타일 컴포넌트에서는 keyframes helper를 사용시 앱 전체에서 사용할 수 있는 고유한 인스턴스를 생성한다.
(다른 파일에서 같은 이름의 keyframes가 존재하더라도 이름 충돌이 나지 않도록 해줍니다.)
`;

 

 

모든 컴포넌트에 styled component처리 할 필요는 없다 아래와 같이 컴포넌트 안에 target으로 scss처럼 사용 가능 peseudo selector

 

const Box = styled.div`
    height: 200px;
    width: 200px;
    background-color: tomato;
    display: flex;
    justify-content: center;
    align-items: center;
    animation: ${rotateAnimation} 1s linear infinite;
    span { //이렇게 css 사용가능 
        font-size: 30px;

        &:hover {
            font-size: 50px;
        }
    }
`;

function App() {
    return (
        <Wrapper>
            <Box>
                <span>😛</span> //span은 컴포넌트가 아님에도 
            </Box>
        </Wrapper>
    );
}

 

위와 같이  element에 의존하여 css를 작성할 때 <span></span>을 <p></p>로 변경하게 된다면 jsx,css 모두 변경해야하는 번거로움이있다. 컴포넌트 이름으로 css를 작성한다면 상관없음 

 

const Emoji = styled.span`
    font-size: 30px;  //평소 css
`;
const Box = styled.div`
    height: 200px;
    width: 200px;
    background-color: tomato;
    display: flex;
    justify-content: center;
    align-items: center;
    animation: ${rotateAnimation} 1s linear infinite;
    ${Emoji} {   // 조건문처럼 box안에 있는 emoji만 적용됨 
            font-size: 50px;  
    }
`;

function App() {
    return (
        <Wrapper>
            <Box>
                <Emoji as="p">😛</Emoji> 엘리먼트롤 p로 변경했음에도 스타일 적용됨 
            </Box>
            <Emoji>🤠</Emoji>
        </Wrapper>
    );

 


themes

다크모드를 구현한다면 50%는 theme의 역할이다.

나머지 50%는 local Estate Management

theme: 모든 색상들을 가지고 있는 object

theme을 실행하기 위해선 index.js로 가야함 

 

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

const darkTheme = { 두개의 컴포넌트
    textColor: "whitesmoke",
    backgroundColor: "#111",
};

const lightTheme = {
    textColor: "#111",
    backgroundColor: "whitesmoke",  //같은 이름의 속성을 갖어야함!
};
ReactDOM.render(
    <React.StrictMode>
        <ThemeProvider theme={lightTheme}>  얘만 바뀌면 다 바껴 다음에는 얘를 어떻게 바꾸어야하는지 배울 것 
            <App />  //app을 ThemeProvider로 감싸줘야하고 theme이라는 props을 가져야한다.!!

                          ThemeProvider 안에 있는 모든 component는이 object에 접근 할 수있다.
        </ThemeProvider>
    </React.StrictMode>,
    document.getElementById("root")
);

 

app.js

const Wrapper = styled.div`
    display: flex;
    width: 100%;
    height: 100vh;
    justify-content: center;
    align-items: center;
    background-color: ${(props) => props.theme.backgroundColor};
    p {
        color: ${(props) => props.theme.textColor}특정 값이 적혀있지 않고 reference만 있음 따라서 바꾸기 용이함
        font-weight: bold;
    }
`;

function App() {
    return (
        <Wrapper>
            <p>Hello</p>
        </Wrapper>
    );
}
export default App;