TIL 21.06.02

Jaemin Jung·2021년 6월 3일
0

Today I Learned

목록 보기
33/62
post-thumbnail

오늘한일

React과제를 통해 직접 StyledComponent를 작성해보고 UI컴포넌트의 기능도 구현해보았다.
StyledComponent에 직접적으로 이해하여 흡수할 수 있는 시간이었다.

Achievement Goals

  • 컴포넌트 기반 CSS 작성에 도움을 주는 라이브러리인 Styled-Component를 활용할 수 있다.
  • DOM Reference를 활용하기 위한 useRef Hook을 활용할 수 있다

StyledComponent 사용법

import styled from "styled-components";

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
`;

StyledComponent 기본적인 사용법은 간단하다.
우선 StyledComponent 라이브러리를 import로 불러와준다.
JacaScript에서 변수를 선언하듯이 스타일 명칭을 작성하고
할당하는 내용에는 첫번째로 styled.html 태그를 작성하며,
이후 백틱안에 CSS문법을 이용하여 스타일 속성을 정의해주는것 뿐이다.

이렇게 생성된 변수는 컴포넌트로 작용하며, props를 전달 받아 속성값을 정의할 수도 있다.

// Button component
...
  background: ${(props) => (props.primary ? "palevioletred" : "white")};
  color: ${(props) => (props.primary ? "white" : "palevioletred")};
...

// App component
...
  <Button>Normal</Button>
  <Button primary>Primary</Button>
...

그리고 기존에 만들어놓은 스타일 컴포넌트를 상속받아 약간의 변화만 줄수도 있다.

// 기존의 Button 컴포넌트에 Tomato 컴포넌트만을 위한 새로운 속성 추가
const Tomato = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

StyledComponent 특징

  • Automatic critical CSS
    Styled Component 는 화면에 어떤 컴포넌트가 렌더링 되었는지 추적해서 해당하는 컴포넌트에 대한 스타일을 자동으로 삽입합니다. 따라서 코드를 적절히 분배해 놓으면 사용자가 어플리케이션을 사용할 때 최소한의 코드만으로 화면이 띄워지도록 할 수 있습니다.

  • No class name bugs
    Styled Component 는 스스로 유니크한 className 을 생성합니다. 이는 className 의 중복이나 오타로 인한 버그를 줄여줍니다.

  • Easier deletion of CSS
    기존에는 더 이상 사용하지 않거나 삭제한 컴포넌트에 해당하는 스타일 속성을 제거하기위해 CSS 파일 안의 className을 이리저리 찾아야 했습니다. 하지만 Styled Component 는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 만약 컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제됩니다.

  • Simple dynamic styling
    className을 일일이 수동으로 관리할 필요 없이 React 의 props 나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적입니다.

  • Painless maintenance
    컴포넌트에 스타일을 상속하는 속성을 찾아 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않습니다.

  • Automatic vendor prefixing
    개별 컴포넌트마다 기존의 CSS 를 이용하여 스타일 속성을 정의하면 될 뿐입니다. 이외의 것들은 Styled Component 가 알아서 처리해 줍니다.

useRef

React를 이용하면 별도의 DOM 주소값을 참조해야할 경우가 생긴다.

  • focus
  • text selection
  • media playback
  • 에니메이션 적용
  • d3.js, greensock 등 DOM 기반 라이브러리 활용

React에서는 이러한 예외적인 상황에서 useRef로 DOM 주소값을 참조하도록 한다.

const 주소값을_담는_그릇 = useRef(참조자료형)
// 이제 주소값을_담는_그릇 변수에 어떤 주소값이든 담을 수 있습니다.
return (
    <div>
      <input ref={주소값을_담는_그릇} type="text" />
        {/* React에서 사용 가능한 ref라는 속성에 주소값을_담는_그릇을 값으로 할당하면*/}
        {/* 주소값을_담는_그릇 변수에는 input DOM 엘리먼트의 주소가 담깁니다. */}
        {/* 향후 다른 컴포넌트에서 input DOM 엘리먼트를 활용할 수 있습니다. */}
    </div>
  );

useRef의 실제 사용 예제

예를들어서 특정 컴포넌트를 focus를 해야할 상황에 그 해당하는 컴포넌트를
가리킬 수 있는 방법이 마땅치 않다. 이럴경우 useRef를 활용한다.
DOM으로 비유하자면 querySelector를 사용하는 상황과 비슷하다.
물론 React에서 querySelector를 사용 못하는것은 아니나, 권고하지 않고있다.
여러 sideEffect가 생길 수 있기 때문이다.

import React, { useRef } from "react";

const Focus = () => {
  const firstRef = useRef(null);
  const secondRef = useRef(null);
  const thirdRef = useRef(null);

  const handleInput = (event) => {
    console.log(event.key, event);
    if (event.key === "Enter") {
      if (event.target === firstRef.current) {
        secondRef.current.focus();
        event.target.value = "";
      } else if (event.target === secondRef.current) {
        thirdRef.current.focus();
        event.target.value = "";
      } else if (event.target === thirdRef.current) {
        firstRef.current.focus();
        event.target.value = "";
      } else {
        return;
      }
    }
  };

  return (
    <div>
      <h1>타자연습</h1>
      <h3>각 단어를 바르게 입력하고 엔터를 누르세요.</h3>
      <div>
        <label>hello </label>
        <input ref={firstRef} onKeyUp={handleInput} />
      </div>
      <div>
        <label>world </label>
        <input ref={secondRef} onKeyUp={handleInput} />
      </div>
      <div>
        <label>codestates </label>
        <input ref={thirdRef} onKeyUp={handleInput} />
      </div>
    </div>
  );
};

export default Focus;

위 코드에서는 세가지 input 태그가 있지만 React에서는 특정 input태그를 찝어낼만한 방법이 마땅치않기에, useRef를 사용하며, 변수처럼 선언한 ref를 각각 태그에 지정해주어 접근이 가능하다.

profile
내가 보려고 쓰는 블로그

0개의 댓글