[프론트엔드 스쿨 6기] 🗓️ 8월11일

유동균·2023년 8월 11일
0

프론트엔드 스쿨 6기

목록 보기
35/44
post-thumbnail

아토믹 컴포넌트

import React from 'react';가 더이상 필요 없는 이유는
import React

Atomic design

1. 배열 역순 정렬 후 렌더링 하기

반드시 복사해서 원본을 파괴하지 말자!!!
=> 배열 복사 또는 새로운 배열 반환 메서드

외부에서 props 전달된 함수를 실행한 결과를 활용

2. 객체 순환해서 렌더링 하기

객체 순환 리스트 렌더링 (객체 → 배열 객체로 변경 → map 메서드로 순환)

<dl> 내부에 <div>를 사용하는 것이 적절한 지 고민한 후 적절하지 않으면 <></>를 사용
<></>의 경우 리스트 렌더링 시 key prop을 설정할 수 없음. 그러므로 <React.Fragment key={} /> 활용해야 함

3. 이벤트 핸들링

onclick ❌, onClick

동작이 되지 않는다!!!

<GoToButton/>에 이벤트를 전달하고 props를 전달하지 않았다.
즉, 이벤트를 전달해줘야한다!!!

...restProps
모든 props를 예측해서 컴포넌트에 적용하기란 쉽지 않다.

3.1 업 다운 버튼 만들기

이벤트 핸들러(리스너) 로직 구성 (DOM 스크립팅 → 사이드 이펙트, 불순 함수 허용)

패칭 데이터 또한 React 렌더링과 연관 없다.

사이드 이펙트란? React 렌더링 과정과 관련 없는 것들(부수적인 것)

behavior: 'smooth'
scroll 부드럽게

3.2 TodoList

따라서 HTML의for임을 명시...

3.2.1 CSS Modules

CSS 클래스 코드를 모듈 객체로 받아와 "고유한 이름"을 사용할 수 있다. 클래스 이름이 같아도 충돌이 나지 않는다.
다른 사람이 작성한 클래스 이름과 절대로 충돌할 일이 없다.
컴포넌트 스타일을 보호할 수 있다.

vite가 기본제공하기 때문에 설치가 필요없이 파일명.module.css


글자에 그라디언트

.container {
  color: yellow;
  & h1 {
    display: inline-flex;
    margin-block: 0;
    font-weight: 900;
    font-size: 5rem;
    color: transparent;
    background: linear-gradient(to right, #534e, #2e2e);
    -webkit-background-clip: text;
    background-clip: text;
  }
}

3.2.2 postCSS config

scope name 설정하기
generateScopedName

기존 class

클래스명 최적화 하기

3.3 이벤트 전파

이벤트 핸들러는 컴포넌트가 가질 수 있는 모든 하위 이벤트도 감지한다.
이벤트가 트리거 되면 버블(bubble) 되어 전파(propagation)된다.

React 앱에서 onScroll을 제외한 모든 이벤트가 전파된다.

export default function Toolbar() {
  return (
    <div className="toolbar" onClick={() => console.log('툴바 클릭!')} >
      <button type="button" onClick={() => console.log('재생!')}>
        영화 재생
      </button>
      <button type="button" onClick={() => console.log('업로드!')}>
        이미지 업로드
      </button>
    </div>
  );
} 

두 버튼 중 하나를 클릭하면 해당 버튼의 onClick prop에 연결된 이벤트 핸들러가 먼저 실행된 후, 상위 요소인 <div>의 onClick prop에 연결된 이벤트 핸들러가 실행

반면 Toolbar 자체를 클릭하면 <div> 요소의 이벤트 핸들러만 실행

3.3.1 이벤트 전파 중지

이벤트 핸들러는 이벤트 객체를 (마지막) 인자로 전달 받는다.
일반적으로 이벤트 객체는 event를 나타내는 e라고 표기하고 이 객체를 사용해 이벤트에 대한 정보를 읽을 수 있다.

해당 이벤트 객체를 사용하면 이벤트 전파를 중지할 수도 있는데,
이벤트가 상위 컴포넌트에 도달하는 것을 방지하려면 Button 컴포넌트 이벤트 핸들러에서 e.stopPropagation()을 호출해야 한다.

function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick?.();
    }}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div className="toolbar" onClick={() => console.log('툴바 클릭!')}>
      <Button onClick={() => console.log('재생!')}>
        영화 재생
      </Button>
      <Button onClick={() => console.log('업로드!')}>
        이미지 업로드
      </Button>
    </div>
  );
}

이벤트 캡쳐
드물게 이벤트 전파를 중지했음에도 하위 요소에서 모든 이벤트를 감지할 수 있어야 하는데, 예를 들어 이벤트 전파 로직과 상관없이 모든 클릭을 분석에 기록하고 싶을 수 있다.
이런 경우 이벤트 이름 뒤에 Capture를 추가하면 캡쳐 이벤트를 사용해 요구된 바를 이행할 수 있다.

<div onClickCapture={() => { /* 캡쳐 이벤트이므로 가장 먼저 실행 됨 */ }}>
  <button onClick={e => e.stopPropagation()} />
  <button onClick={e => e.stopPropagation()} />
</div>

각 이벤트는 3단계로 전파된다.
1. 상위 요소의 onClickCapture 이벤트 핸들러가 실행.
2. 버튼 요소의 onClick 이벤트가 실행.
3. 버튼 요소에서 이벤트 전파가 중단되었으므로 상위 요소의 이벤트는 중지.

3.3.2 이벤트 전파 대안﹕핸들러 전달

function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick?.();
    }}>
      {children}
    </button>
  );
} 

이 방법은 이벤트 핸들러를 호출하기 전에 보다 많은 코드를 포함할 수 있고, 이벤트 전파를 대신할 수 있다.
하위 컴포넌트가 이벤트를 처리하는 동시에 상위 컴포넌트가 일부 추가 기능이 작동되도록 지정할 수 있으며 이벤트 전파와 달리 자동으로 처리되지 않는다.

0개의 댓글