[06.16] Custom Component

0
post-thumbnail

목차

  • CDD
  • 구조적인 CSS 작성 방법의 발전
  • CDD 개발 도구
  • Storybook
  • useRef

📌 CDD

: 재사용이 가능한 UI컴포넌트를 미리 디자인하고 사용하는 개발 방법(부품 단위로 UI컴포넌트를 만들어 나가는 개발) -> 상향식 개발

[예시]
기획자가 요청한 웨데이터의 버튼이 같은 모양으로 다른 위치에 옮기는 걸 요청할때,
새로운 버튼을 만들고 전체 페이지를 렌더링하는게 아니라 버튼 컴포넌트를 만들어놓고 재사용하면서 위치만 변경 시킴

📌 구조적인 CSS 작성 방법의 발전

< 구조화된 CSS가 필요하게 된 이유 : CSS 단점 >

  • 선택자를 만들때 매번 불필요한 부모요소 선택자가 필요
  • 함수가 없으니 규모가 큰 프로젝트의 경우 자동화하기 어렵고 모든 것을 수동으로 변경
  • CSS 작성에 일관된 패턴이 없음
  • 모바일, 태블릿을 비롯한 다양한 디바이스에 맞춰 디스플레이를 커버해야하니 CSS파일이 더 복잡해지게 됨 (유지보수 마이너스)

< 문제 해결 >

  • CSS 전처리기(CSS가 만들어지기 전에 수행) 등장
    : CSS가 구조적으로 작성될 수 있게 도움을 주는 도구

    💡 전처리기란?
    처리에 있어서 중심적인 처리를 수행하는 부분을 위해 준비적인 계산을 함

  • 전처리기 언어는 CSS 문법과 거의 유사하지만 선택자의 중첩, 조건문, 반복문 등 표준 CSS보다 더 많은 기능을 사용해서 편리하게 작성 가능
    -> 코드 작성 시간은 줄고, 코드를 유지 관리하는데 도움이 됨
  • 단점
    • CSS 전처리기 자체만으로는 웹 서버가 인지하지 못해서 해당 전처리기에 맞는 Compiler를 사용해서 실제로 우리가 사용하는 CSS 문서로 변화시켜줌
    • 내부에서 어떤 작업을 하고 있는지 알지 못한 채 스타일이 겹치는 문제를 해결하귀 위해 단순치 계층 구조를 만들어 내는 것에 의지 -> 컴파일된 CSS 용량이 커짐

전처리기 언어(Sass)

: Sass는 CSS 대체의 언어가 아닌 CSS의 확정 전처리기 언어이고 결국 CSS 코드를 생산해내기 위해 사용하는 일종의 도구

CSS 방법론

: CSS 전처리기의 문제를 보완하기 위해 BEM, OOCSS, SMACSS 같은 CSS 방법론이 나옴

  • BEM(Black Element Modifier)
    : Black, Element, Modifier로 구분하여 클래스명 작성
    -> 클래스명음 BEM 방식의 이름을 여러번 반복하여 재사용할 수 있도록 하고 HTML/CSS/SASS 파일에서도 더 일관된 코딩 구조를 만들어줌
    • block : 재사용이 가능하고 기능적으로 독립적인 페이지 component
      (블럭은 블럭을 감쌀 수 있음 .header>.logo
    • Element : 블럭을 구성하는 단위
      - 블럭은 독립적인 형태, 엘리먼트는 의존적인 형태
      - 자신이 속한 블럭내에서만 의미를 가져서 블럭안에서 떼어다가 쓸 수 없음
    • Modifier : 블럭이나 엘리먼트의 속성
      (블럭과 엘리먼트의 외관이나 상태를 변화하게 함)

SASS와 BEM의 단점

: 언어 로직 상에 진정한 캡슐화(객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉)의 개념이 없음

-> 이로 인해 개발자들이 유일한 클래스명을 선택하는 것에 의존

애플리케이션으로 개발 방향이 진화되면서 컴포넌트 단위의 개발은 캡술화의 중요성이 대두
-> CSS를 컴포넌트 방식으로 만들기 위해 CSS-in-JS 탄생


📌 CDD 개발 도구

Styled Components

Styled Components를 다루기 전에 CSS 사용시 불편했던 점

  • class, id 작명에 대한 고민

  • CSS 파일 안에서 찾고자 하는 부분 찾기 힘듬

  • CSS 파일안의 용량이 너무 많아 파일을 쪼개서 관리

  • 스타일 속성이 겹쳐서 내가 원하는 결과가 나오지를 않음

    ➡️ 이런 단점들을 해결해줄 라이브러리가 바로 Styled Components

CSS in JS 라이브러리를 사용하면 CSS도 쉽게 Javascript안에 넣어줄 수 있고, HTML+JS+CSS까지 묶어서 하나의 JS파일 안에서 컴포넌트 단위로 개발을 할 수 있음
➡️ CSS in JS 라이브러리 중에서 가장 인기 있는 라이브러리가 바로 Styled Components

Styled Components 설치방법

  // with npm
  npm install --save styled-components@latest
  
  //with yarn
  yarn add styled-components

Styled Components 문법

  1. 컴포넌트 만들기 (링크)

    • Templete Literals 문법 사용(`)
    • 컴포넌트를 선언 후 styled.태그종류를 할당하고, 백틱안에 기존에 CSS를 작성하던 문법과 동일하게 스타일 속성을 작성
  2. 컴포넌트를 재활용해서 새로운 컴포넌트 만들기 (링크)
    : 이미 만들어진 컴포넌트를 재활용해서 새로운 컴포넌트를 만들 수 있음
    styled()에 재활용할 컴포넌트를 전달해준 다음에 추가하고 싶은 스타일 속성 작성

  3. props 활용하기
    : Styled Component로 만든 컴포넌트를 react 컴포넌트처럼 props로 내려줄 수 있으며 내려준 props 값에 따라서 컴포넌트를 렌더링 하는 것도 가능
    `${}을 사용해서 Javascript코드를 사용할 수 있음

    1) Props로 조건부 렌더링하기 (링크)
    [예시]
    <button>컴포넌트에 skyblue라는 props가 있는지 확인하고 있으면 배경색을 skyblue로 지정, 없으면 `white로 지정해주는 코드 작성

    2) Props 값으로 렌더링하기 (링크)
    [예시]
    - props의 값을 통째로 활용해서 컴포넌트 렌더링에 활용
    - props.color가 없다면 whiteprops.color가 있다면 props.color의 값을 그대로 가져와서 스타일 속성 값으로 리턴해줌 (2개 이미지는 같은 결과값을 가져옴)

  4. 전역 스타일 설정하기
    - 전역 스타일 설정을 위해 Styled Components에서 createGlobalStyle 함수를 불러옴
    import { createGlobalStyle } from "styled-components";
    - ccs 스타일 작성

    	const GlobalStyle = createGlobalStyle`
    	button {
    		padding : 5px;
    		margin : 2px;
     	border-radius : 5px;
    	}
    `

    - 컴포넌트를 최상위 컴포넌트에 사용

    function App() {
    	return (
    		<>
    			<GlobalStyle />
    			<Button>전역 스타일 적용하기</Button>
    		</>
    	);
    }

📌 Storybook

: UI 개발, Component Driven Development를 하기 위한 도구

  • 컴포넌트의 재사용성, 테스트, 개발속도 향상
    -> 시물레이션을 통해 버그를 사전에 방지 가능
  • 컴포넌트를 문서화 및 시각화 가능
  • 특정 프로젝트에 종속되는 라이브러리가 아닌 독립적인 개발 환경에서 실행됨
    -> 개발자는 애플리케이션의 다양한 상황에 구애받지 않고 UI 컴포넌트를 집중적으로 개발이 가능함

Storybook 사용 방법

  1. 리액트 프로젝트 생성
    npx create- react-app storybook-practice
  2. 폴더가 생성되면 폴더 안에서 해당 명령어를 입력하여 storybook 설치
    npx storybook@latest init
  3. storybook 실행
    npm run storybook

📌 useRef

: React 애플리케이션을 만들때 DOM을 직접 조작하는 것은 권장되지 않지만, 개발을 하다보면 DOM을 직접 조작해야하는 상황이 발생함

➡️ 이럴때 사용하는 것이 바로 useRef

  • DOM노드, 엘리먼트, React 컴포넌트 주소값을 참조할 수 있음
  • 렌더링이 되지 않기 때문에 값이 변하지 않게 구현됨
    하지만, 내부적으로는 값이 변하고 있는건 맞음

[예시]

  import React, { useState, useRef } from 'react';
  
  const App = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(0);
  
  console.log ('🎨 렌더링..');
  // useState함수를 클릭하면 전체 화면의 리렌더링이 되면서 state값이
  // 올라가고 내부적으로 올라갔던 ref의 증가된 값도 나타남
  const increasecounetState= () => {
  	setCount(count + 1);
  };
  
  // useRef는 렌더링이 되지 않기 때문에 내부적으로는 
  // 값이 1씩 증가하지만 표시되지 않음
  const increaseCountRef = () => {
  	countRef.current = countRef.current + 1;
  	console.log('Ref: ', countRef.current);
  };
  
  return (
  	<div>
      <p>State: {count}</p>
      <p>Ref: {countRef.current}</p>
      <button onClick={increaseCountState}>State 올려</button>
      <button onClick={increaseCountRef}>Ref 올려</button>
  	</div>
  );  
};

0개의 댓글