프론트엔드 첫걸음

Styled Component 사용하기 ( props 사용해서 동적으로 스타일링 ) 본문

개발 공부/React

Styled Component 사용하기 ( props 사용해서 동적으로 스타일링 )

차정 2022. 7. 22. 18:45

1. 설치

터미널을 열고 해당 리액트프로젝트내에서 npm install --save styled-components 명령어 입력
=> styled component 설치

styled component 사용할 파일 상위에 import styled from 'styled-components' 입력

 

2. 사용

styled.button`
styled.a`
styled.div`
  • Styled components는 위와 같은 코드로 시작한다.
    styled는 styled-components에서 import하는 객체이고,
    이 객체를 통해 button, a, div 메소드에 접근할 수 있는 것이다.
    이 메소드에 백틱으로 만든 리터럴을 넘겨주는 것인데, 이것은 Tagged Templated literal 이라는 문법이다.
  • const Button = styled.button` : styled 객체가 button 메소드를 호출하면 button 요소를 반환한다.
    이 때 백틱 뒤에 리터럴로 넣어준 css 스타일이 반환하는 button 요소에 영향을 미치는 것.
.form-control {
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
}

.form-control input:focus {
  background: lightblue;
}

.form-control.invalid label {
  font-weight: bold;
}
  • 이러한 스타일을 styled components 사용하려고 하면 ?
const FormControl = styled.div `
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;

  & input:focus {
    background: lightblue;   
  }

  &.invalid label {
    font-weight: bold;
  }
`
  • 선택자(.form-control) 는 삭제하고 가상선택자의 경우 styled-components에서 지원하는 &기호를 사용하여 & focus 이렇게 사용한다.
  • 해당 styled component 는 아래와 같이 사용한다.
const CourseInput = props => {
  const [enteredValue, setEnteredValue] = useState('');
  const [isValid, setIsValid] = useState(true);

  return (
    <form onSubmit={formSubmitHandler}>
      <FormControl inValid={isValid}>
        <label>Course Goal</label>
        <input type="text" onChange={goalInputChangeHandler} />
      </FormControl>
      <Button type="submit">Add Goal</Button>
    </form>
  );
 };

 export default CourseInput;

 

다른 예시 
[출처] 벨로퍼트와 함께하는 모던 리액트 3-1 
 https://react.vlpt.us/mashup-todolist/01-create-components.html

import React from 'react';
import styled from 'styled-components';

const TodoHeadBlock = styled.div`
  padding-top: 48px;
  padding-left: 32px;
  padding-right: 32px;
  padding-bottom: 24px;
  border-bottom: 1px solid #e9ecef;
  h1 {
    margin: 0;
    font-size: 36px;
    color: #343a40;
  }
  .tasks-left {
    color: #20c997;
    font-size: 18px;
    margin-top: 40px;
    font-weight: bold;
  }
`;

function TodoHead() {
  return (
    <TodoHeadBlock>
      <h1>2019년 7월 10일</h1>
      <div className="tasks-left">할 일 2개 남음</div>
    </TodoHeadBlock>
  );
}

export default TodoHead;

 Styled Component로 감싸면,  Styled Component에 적용된 css 가 그 하위의 요소에도 영향을 미친다.
하위의 요소에 관한 css를 상위의 Styled Component에 작성한다.

 

3.  동적으로 스타일 주기 

styled component 는 props를 추가해서 동적인 스타일링이 가능하다.

예시 1 - 속성 : props 함수

const FormControl = styled.div `
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;

  & input:focus {
    background: ${props => props.inValid ? 'grey' : 'lightblue'};   
  }

  &.invalid label {
    font-weight: bold;
  }
`

const CourseInput = props => {
  const [enteredValue, setEnteredValue] = useState('');
  const [isValid, setIsValid] = useState(true);

  return (
    <form onSubmit={formSubmitHandler}>
      <FormControl inValid={!isValid}>
        <label>Course Goal</label>
        <input type="text" onChange={goalInputChangeHandler} />
      </FormControl>
      <Button type="submit">Add Goal</Button>
    </form>
  );
 };

 export default CourseInput;
  • isValid 상태에 따라 동적으로 스타일을 다르게 주기 위해 FormControl 컴포넌트에 props로 isValid의 상태값을 넘겨주었다.
    ( isValid가 false면 invalid는 true
  • background: ${props => props.inValid ? 'grey' : 'lightblue'};
    inValid true 면 background 색을 grey로 inValid false 면 background 색을 lightblue로 한다.

 

예시 2 - props 함수안에 속성  

const CheckCircle = styled.div`
  width: 32px;
  height: 32px;
  border-radius: 16px;
  border: 1px solid #ced4da;
  font-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 20px;
  cursor: pointer;
  ${props =>
    props.done &&
    css`
      border: 1px solid #38d9a9;
      color: #38d9a9;
    `}
`;

 

이런식으로 props 함수 안에 속성의 상태를 넣을 수 도 있다.
(props의 조건에 따라 바뀌는 속성이 많을 때 이렇게 사용하면 깔끔하다)

 

미디어 쿼리도 사용 가능하다 

const FormControl = styled.div `
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  width: 100%

  & input:focus {
    background: ${props => props.inValid ? 'grey' : 'lightblue'};   
  }

  &.invalid label {
    font-weight: bold;
  }

  @media (min-width: 768px){
  	width: auto;
  } 
`


const CourseInput = props => {
  const [enteredValue, setEnteredValue] = useState('');
  const [isValid, setIsValid] = useState(true);

  return (
    <form onSubmit={formSubmitHandler}>
      <FormControl inValid={!isValid}>
        <label>Course Goal</label>
        <input type="text" onChange={goalInputChangeHandler} />
      </FormControl>
      <Button type="submit">Add Goal</Button>
    </form>
  );
 };

 export default CourseInput;

 

 

 

[참고]

https://styled-components.com/