아토믹 컴포넌트
import React from 'react';
가 더이상 필요 없는 이유는
import React
반드시 복사해서 원본을 파괴하지 말자!!!
=> 배열 복사 또는 새로운 배열 반환 메서드
외부에서 props 전달된 함수를 실행한 결과를 활용
객체 순환 리스트 렌더링 (객체 → 배열 객체로 변경 → map 메서드로 순환)
<dl>
내부에 <div>
를 사용하는 것이 적절한 지 고민한 후 적절하지 않으면 <></>
를 사용
<></>
의 경우 리스트 렌더링 시 key prop을 설정할 수 없음. 그러므로 <React.Fragment key={} />
활용해야 함
onclick
❌, onClick
✅
동작이 되지 않는다!!!
<GoToButton/>
에 이벤트를 전달하고 props를 전달하지 않았다.
즉, 이벤트를 전달해줘야한다!!!
...restProps
모든 props를 예측해서 컴포넌트에 적용하기란 쉽지 않다.
이벤트 핸들러(리스너) 로직 구성 (DOM 스크립팅 → 사이드 이펙트, 불순 함수 허용)
패칭 데이터 또한 React 렌더링과 연관 없다.사이드 이펙트란? React 렌더링 과정과 관련 없는 것들(부수적인 것)
behavior: 'smooth'
scroll 부드럽게
따라서 HTML의for임을 명시...
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; } }
scope name 설정하기
generateScopedName
기존 class
클래스명 최적화 하기
이벤트 핸들러는 컴포넌트가 가질 수 있는 모든 하위 이벤트도 감지한다.
이벤트가 트리거 되면 버블(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>
요소의 이벤트 핸들러만 실행
이벤트 핸들러는 이벤트 객체를 (마지막) 인자로 전달 받는다.
일반적으로 이벤트 객체는 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. 버튼 요소에서 이벤트 전파가 중단되었으므로 상위 요소의 이벤트는 중지.
function Button({ onClick, children }) {
return (
<button onClick={e => {
e.stopPropagation();
onClick?.();
}}>
{children}
</button>
);
}
이 방법은 이벤트 핸들러를 호출하기 전에 보다 많은 코드를 포함할 수 있고, 이벤트 전파를 대신할 수 있다.
하위 컴포넌트가 이벤트를 처리하는 동시에 상위 컴포넌트가 일부 추가 기능이 작동되도록 지정할 수 있으며 이벤트 전파와 달리 자동으로 처리되지 않는다.