Engineering
React 핵심 패턴
React 핵심 패턴 학습 내용을 정리한 백필 노트입니다.
이 글은 2025년 학습 기록을 블로그 형식으로 정리한 백필 노트입니다.
1. JSX 기본 문법 및 구조
컴포넌트 구조
.jsx파일 하나를 '컴포넌트'라고 부르며, 함수 형태로 작성합니다.- 컴포넌트 이름은 파스칼 케이스(PascalCase)로 작성하는 것이 관례입니다.
- React 17 버전부터는
import React from 'react'코드를 명시하지 않아도 됩니다.
JSX Fragment (<>...</>)
- React 컴포넌트는 반드시 하나의 최상위 요소만 반환해야 합니다.
- 불필요한
<div>래퍼(wrapper) 생성을 피하기 위해, 여러 요소를</>(Fragment)로 감싸면 실제 DOM에는 추가되지 않습니다. - Fragment에
key와 같은 속성을 전달해야 할 경우,import { Fragment } from 'react'후<Fragment>컴포넌트를 명시적으로 사용합니다.
데이터 보간(Interpolation)
-
JSX 내에서
{}중괄호를 사용하여 JavaScript 변수나 표현식의 결과를 출력할 수 있습니다.JavaScriptconst name = 'React'; return <h1>Hello, {name}!</h1>; // 출력: Hello, React!
2. 데이터 관리와 렌더링
반응형 데이터 (useState)
-
데이터가 변경될 때 화면이 자동으로 업데이트되는 데이터를 '반응형 데이터'라고 합니다.
-
useStateHook을 사용하여 선언하고 관리합니다.JavaScriptimport { useState } from 'react'; // const [데이터, 데이터변경함수] = useState(초기값); const [count, setCount] = useState(0); // 데이터 변경 setCount(count + 1);
이벤트 핸들링 (onEvent)
-
HTML 요소에 이벤트를 연결할 때는
on접두사와 카멜 케이스(camelCase)로 작성된 이벤트 속성을 사용합니다. (예:onClick,onChange)JavaScript<button onClick={() => setCount(count + 1)}>증가</button>
HTML 속성 바인딩
- 클래스 (
className): JavaScript의 예약어class와 충돌을 피하기 위해className속성을 사용합니다. 조건부 클래스는 템플릿 리터럴이나 삼항 연산자를 활용합니다. - 인라인 스타일 (
style):style속성에는 JavaScript 객체를 전달하며, CSS 속성은 카멜 케이스(예:fontSize)로 작성합니다.
조건부 렌더링
-
논리 연산자 (
&&): 조건이 참일 때만 특정 요소를 렌더링합니다.JavaScript{ isLoggedIn && <p>환영합니다!</p> } -
삼항 연산자 (
? :): 조건에 따라 두 가지 다른 결과를 렌더링합니다.JavaScript{ isLoggedIn ? <p>로그아웃</p> : <p>로그인</p> } -
복잡한 조건:
if/else와 같이 복잡한 조건은 JSX 밖에서 별도의 함수로 처리한 후 호출하여 사용합니다.
리스트 렌더링 (.map())
-
배열 데이터를 화면에 목록으로 출력할 때
.map()메소드를 사용합니다. -
React가 각 항목을 효율적으로 추적하고 업데이트할 수 있도록, 반복되는 각 요소에는 반드시 고유한
key속성을 문자나 숫자로 지정해야 합니다.JavaScript<ul> {items.map(item => <li key={item.id}>{item.name}</li>)} </ul>
3. React Hooks 심화
계산된 데이터 (useMemo)
-
특정 반응형 데이터가 변경될 때만 연관된 값을 다시 계산하는 최적화 Hook입니다.
-
의존성 배열에 포함된 데이터가 변경될 때만 콜백 함수가 실행됩니다.JavaScript
const double = useMemo(() => count * 2, [count]);
데이터 감시 (useEffect)
-
특정 데이터의 변경을 감지하여 부수 효과(side effect, 예: API 호출)를 실행하는 Hook입니다.
-
의존성 배열에 감시할 데이터를 전달합니다.JavaScript
useEffect(() => { console.log('count가 변경되었습니다.'); }, [count]); -
참고: 개발 모드에서
useEffect가 두 번 실행되는 것은<React.StrictMode>때문이며, 프로덕션 빌드에는 영향을 주지 않습니다.
4. 양식(Form) 입력 바인딩
useState를 사용하여 폼 요소의 값을 반응형 데이터와 양방향으로 연결합니다.
- 텍스트 / 여러 줄 텍스트:
value와onChange를 바인딩합니다. - 수정 가능 요소:
contenteditable속성은 React에서 문제를 일으킬 수 있어react-contenteditable라이브러리 사용을 권장합니다. - 단일/다중 체크박스:
checked와onChange를 바인딩하며, 다중 선택 시 배열로 상태를 관리합니다. - 라디오 버튼: 여러 버튼이 하나의 상태를 공유하도록
checked={state === value}와 같이 설정합니다. - 단일/다중 선택:
<select>의value와onChange를 바인딩하며, 다중 선택(multiple) 시 배열로 상태를 관리합니다.
5. 컴포넌트 심화
템플릿(요소) 참조 (useRef)
-
DOM 요소에 직접 접근해야 할 때
useRef를 사용합니다. -
ref속성을 요소에 연결하고,ref객체.current를 통해 요소에 접근할 수 있습니다.JavaScriptconst inputRef = useRef(null); useEffect(() => inputRef.current.focus(), []);
생명주기 훅 (useEffect)
useEffect의 의존성 배열을 비워두면([]), 컴포넌트가 처음 화면에 렌더링된 후(Mounted) 한 번만 실행되어 생명주기처럼 활용할 수 있습니다.
부모-자식 관계와 Props
-
Props: 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하는 방법입니다. HTML의 속성처럼 전달합니다.
-
폴스루(Fallthrough) 속성:
...restProps패턴을 사용하여, 명시적으로 정의되지 않은 Props를 자식 컴포넌트 내부의 특정 HTML 요소에 그대로 전달할 수 있습니다. -
슬롯(Slot):
children이라는 약속된 Prop을 통해, 부모 컴포넌트에서 자식 컴포넌트의 특정 위치에 JSX를 삽입할 수 있습니다.JavaScript// <Button>여기에 삽입할 내용</Button> function Button({ children }) { return <button>{children}</button>; }
6. 스타일링
CSS 모듈 (.module.css)
-
일반 CSS는 전역으로 적용되어 스타일 충돌이 발생할 수 있습니다.
-
파일 이름을
.module.css로 지정하면 해당 컴포넌트에만 스타일이 적용되도록 범위가 제한(Scoped)됩니다.JavaScriptimport styles from './MyComponent.module.css'; <div className={styles.myClass}>...</div>
SCSS 구성
- Vite 프로젝트에서는
sass패키지만 설치하면 별도 설정 없이 SCSS를 사용할 수 있습니다. (npm i -D sass) - CSS 모듈과 동일하게
.module.scss로 사용 가능하며, 중첩(Nesting) 문법 등으로 유연한 스타일 관리가 가능합니다.
전역 스타일 적용 (:global)
-
CSS 모듈 파일 내에서 특정 선택자를 전역으로 적용하고 싶을 때
:global선택자를 사용합니다.CSS:global .global-class { /* 전역 스타일 */ }