본문 바로가기

WINK-(Web & App)/React.js 스터디

[2024 여름방학 React.js 스터디] 이가인 #5주차

반응형

리액트에서 컴포넌트를 스타일링 하는 가장 기본적인 방법:

         css 파일을 만들어서 컴포넌트에서 import 해서 사용하는 것 

  1. Sass
  2. CSS Module
  3. styled-components

 


1. Sass

  • 시작
    • node-sass 라이브러리 설치(Sass->CSS변환)  

 

cd styling-with-sass $ yarn add node-sass​

 

Button 컴포넌트 만들기

  • & : 부모 선택자 참조 

 

$blue: #228be6; // 주석 선언 
 background: $blue; // 주석 사용 
   &:hover { //:hover 상태(사용자가 요소 위에 마우스를 올렸을 때) 
    background: lighten($blue, 10%); // 색상 10% 밝게 } 
   &:active { //:active상태 (사용자가 요소를 클릭할 때) 
    background: darken($blue, 10%); // 색상 10% 어둡게 }​
  • background: darken($blue, 10%);   --> CSS에는 없는 문법 ( darken(), lighten() )
    • 이 코드의 의미는 $blue 색상을 기준으로 10% 더 어둡게(darken) 만든 색상을 background 속성에 적용하라는 것입니다. 즉, 요소가 클릭되었을 때 배경 색상이 어두워짐

 


 

버튼 사이즈 설정

  •  className 에 CSS 클래스 이름을 동적으로 넣어주고 싶으면 이렇게 설정을 해주어야 함
    • className={`Button ${size}`}     또는   className={['Button', size].join(' ')}

 

  • 조건부로 CSS 클래스를 넣어주고 싶을때 이렇게 문자열을 직접 조합해주는 것 보다 classnames  라는 라이브러리를 사용하는 것이 훨씬 편함  
    •  
    • $ yarn add classnames // 설치
    • 조건부 스타일링 이란??? 
      • 특정 조건에 따라 스타일을 다르게 적용하는 것을 의미
      • 다양한 상황에서 UI 요소의 스타일을 동적으로 변경해야 할 때 유용
      • classNames 를 사용하면 조건부 스타일링을 할 때 함수의 인자에 문자열, 배열, 객체 등을 전달하여 손쉽게 문자열을 조합 할 수 있음
  • function Button({ children, size }) {
      return <button className={classNames('Button', size)}>{children}</button>;
    }   //props 로 받은 props 값이 button 태그의 className 으로 전달

  • .Button {
      &.large {  //&는 부모 선택자인 .Button을 가리킴
      }
     } // 사이즈 설정  = .Button.large 와 같은 거임!!!

- >' .Button 클래스를 가진 요소에 large 클래스가 함께 적용되었을 때만 특정 스타일을 적용하겠다 ' 라는 뜻!!

  • .Button
    & + & {
        margin-left: 1rem;
      }  
      
      //.Button + .Button 를 의미, 만약 함께 있다면 우측에 있는 버튼에 여백 설정

 


버튼 색상 관리 ( 반복되는 코드 : mixin 기능 사용해서 단순화! )

&.pink {
    background: $pink;
    &:hover {
      background: lighten($pink, 10%);
    }

    &:active {
      background: darken($pink, 10%);
    }

이런 코드가 props 값만 바뀌고 다 반복되는 상황이면

아래 코드처럼 변환 가

@mixin button-color($color) {
  background: $color;
  &:hover {
    background: lighten($color, 10%);
  }
  &:active {
    background: darken($color, 10%);
  }
  
  &.pink {
    @include button-color($pink);
  }

 

 


outline 옵션

요소의 경계 외부에 그려지는 선을 정의하는 속성 

시각적 요소이며 처음 정의할 때(구현방식)은 아래와 같이 정의,

outline 값을 props 로 받아와서 객체 안에 집어 넣은 다음에 classNames() 에 포함시킴

-> outline 값이 true 일 때에만 button  outline CSS 클래스가 적용

//설정
function Button({ children, size, color, outline }) {
  return (
    <button className={classNames('Button', size, color, { outline })}>
      {children}
    </button>
  );
}
//불러올 때
<div className="buttons">
        <Button size="large" color="blue" outline>
          BUTTON
        </Button>
        <Button color="gray" outline>
          BUTTON
        </Button>
        <Button size="small" color="pink" outline>
          BUTTON
        </Button>
      </div>

 


fulllWidth 옵션 

요소가 부모 컨테이너의 전체 너비를 차지하도록 설정하는 데 사용

outline옵션과 설정하는 방법은 같다. 

&.fullWidth {
    width: 100%;               // .fullWidth 클래스가 적용된 요소의 너비를 100%로 설정하여, 부모 요소의 전체 너비를 차지하도록 합니다.
    justify-content: center;   // flexbox 컨테이너에서 요소의 자식들을 가로축(수평)에서 중앙에 배치하도록 설정합니다.
    
    & + & {
      margin-left: 0;         // .fullWidth 클래스가 연속적으로 배치된 경우, 다음 요소의 왼쪽 여백을 0으로 설정합니다.
      margin-top: 1rem;       // 연속적인 .fullWidth 요소들 사이에 1rem의 위쪽 여백(간격)을 추가합니다.
    }
}


 

다른 컴포넌트 또는 HTML 태그에 전달하는 상황

spread 와 rest  이용

JavaScript에서 주로 함수의 인자, 배열, 객체에서 사용되며, 여러 개의 값을 하나의 배열이나 객체로 모아주는 역할을 하며,이를 통해 코드의 가독성과 유연성을 높일 수 있다.

 spread:객체 혹은 배열을 펼칠 수 있음. (복사 개념으로,,)  
...[객체/배열이름]
rest는 ...뒤에 변수이름 아님!!(( ...value와 ...rest가 있음))

const purpleCuteSlime = {
  name: '슬라임',
  attribute: 'cute',
  color: 'purple'
};

const { color, ...rest } = purpleCuteSlime;
console.log(color); // purple
console.log(rest); // {name: '슬라임', attribute:'cute'}}
function Button({ children, size, color, outline, fullWidth, ...rest }) {
  return (
    <button
      className={classNames('Button', size, color, { outline, fullWidth })}
      {...rest}
    >
      {children}
    </button>
  );
}

 ...rest를 사용해서 우리가 지정한 props 를 제외한 값들을 rest 라는 객체에 모아주고, <button> 태그에 {...rest} 를 해주면, rest 안에 있는 객체안에 있는 값들을 모두 <button> 태그에 설정

 

rest에 어느 props가 올지모르지만 앞에 지정한 props외 모두가 올 수 있음 ( 앞에 지정한 props의 여집합)

 

함수 파라미터에서의 rest

함수의 파라미터가 몇개가 될 지 모르는 상황에서 rest 파라미터를 사용하면 매우 유용


2. CSS Module 

이 기술의 장점

CSS 클래스가 중첩되는 것을 완벽히 방지 가능, 명확한 의존관계가 잘 보임!

리액트 컴포넌트 파일에서 해당 CSS 파일을 불러올 때 CSS 파일에 선언한 클래스 이름들이 모두 고유해짐

실수로 CSS 클래스 이름이 다른 관계 없는 곳에서 사용한 CSS 클래스 이름과 중복되는 일에 대하여 걱정 할 필요가 없음

ex)

function Component() {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Hello, CSS Modules!</h1>
    </div>
  );
}

 

import React from 'react';
import { MdCheckBox, MdCheckBoxOutlineBlank } from 'react-icons/md';
import styles from './CheckBox.module.css';

function CheckBox({ children, checked, ...rest }) { 
  return (
    <div className={styles.checkbox}>
      <label>
        <input type="checkbox" checked={checked} {...rest} />
        <div className={styles.icon}>
          {checked ? (
            <MdCheckBox className={styles.checked} />
          ) : (
            <MdCheckBoxOutlineBlank />
          )}
        </div>
      </label>
      <span>{children}</span>
    </div>
  );
}

export default CheckBox;

 

 

 


3. styled-components

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

const Circle = styled.div`
  width: 5rem;
  height: 5rem;
  background: black;
  border-radius: 50%;
`;

function App() {
  return <Circle />;
}

export default App;

 

Template Literal( 템플릿 리터럴(`))

const object = { a: 1 };
const text = `${object}`; // 이 코드에서 object.toString()이 자동으로 호출됨
console.log(text); // "[object Object]" 출력
const red = '빨간색';
const blue = '파란색';

function favoriteColors(texts, ...values) {
  console.log(texts);
  console.log(values);
}
favoriteColors`제가 좋아하는 색은 ${red}과 ${blue}입니다.`

 

  • texts 배열: 템플릿 리터럴의 정적인 문자열 부분들이 배열로 들어간다.
  • values 배열: 템플릿 리터럴에서 ${} 안에 삽입된 값들이 배열로 들어간다.
console.log(texts); // ["내가 좋아하는 색은 ", "와 ", "입니다."]
console.log(values); // ["빨간색", "파란색"]

 

반응형