728x90
React란 무엇인가
React는 사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리이다. Facebook에서 개발하였으며, 컴포넌트 기반 구조와 Virtual DOM 개념을 통해 효율적인 화면 업데이트를 가능하게 한다.
React의 핵심 개념
컴포넌트(Component)
- 하나의 UI 단위를 뜻한다.
- 함수형 컴포넌트가 주로 사용되며, JSX(JavaScript XML)를 통해 마크업을 작성한다.
JSX
- JavaScript와 HTML을 섞은 문법이다.
- class 대신 className, for 대신 htmlFor를 사용한다.
Props (속성)
- 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달할 때 사용한다.
- 읽기 전용이다.
State (상태)
- 컴포넌트 내부에서 관리하는 값이다.
- 값이 변경되면 컴포넌트가 리렌더링된다.
Hook 설명
Hook은 함수형 컴포넌트에서 상태 관리 및 생명주기 기능을 사용할 수 있도록 하는 함수이다. 각 훅은 특정 목적과 시점에 맞춰 사용되며, 일반적으로 함수형 컴포넌트의 최상단에서만 호출되어야 한다.
useState
const [state, setState] = useState(initialState);
- 첫 번째 인자: 초기 상태값. 보통 숫자, 문자열, 객체, 배열 등 자유롭게 지정 가능하다.
- 두 번째 인자: 상태를 갱신하는 함수이며, 비동기적으로 작동한다.
- 언제 쓰는가: 사용자 입력, 체크 상태, 모달 on/off 등 간단한 상태가 필요한 경우에 유용하다.
- 주요 특징: 상태가 변경되면 컴포넌트가 다시 렌더링된다.
useEffect
useEffect(() => {
// 부수 효과 실행
return () => {
// 정리 함수 (unmount 시 동작)
};
}, [dependencies]);
- 첫 번째 인자: 실행할 콜백 함수. 주로 side effect를 처리하는 코드가 들어간다.
- 두 번째 인자: 의존성 배열. 배열 안의 값이 바뀔 때만 effect가 다시 실행된다.
- 언제 쓰는가: 컴포넌트가 마운트될 때, 값이 변경될 때, API 요청, 이벤트 리스너 등록 등에서 활용된다.
useContext
const value = useContext(MyContext);
- 첫 번째 인자: React.createContext()로 만든 Context 객체
- 언제 쓰는가: 로그인 정보, 다크 모드 설정과 같은 전역 상태를 여러 컴포넌트에서 공유할 때 유용하다.
- 주의: Context Provider 하위에서만 작동하며, Provider에 전달된 value를 자동으로 추적하여 반영한다.
useReducer
const [state, dispatch] = useReducer(reducerFn, initialState);
- 첫 번째 인자: reducer 함수. (state, action) => newState 형식
- 두 번째 인자: 초기 상태값
- 언제 쓰는가: 상태 업데이트 로직이 복잡하거나, 여러 상태값이 관련되어 있을 때
- useState와의 차이점: useReducer는 상태 변경 방식이 명확하며 예측 가능하다. 특히 Redux 스타일 아키텍처와 유사하다.
useRef
const myRef = useRef(initialValue);
- 첫 번째 인자: 초기값 (대개 null 또는 숫자 등)
- 언제 쓰는가: DOM 요소에 직접 접근하거나, 렌더링 없이 값을 기억하고 싶을 때
- useState와의 차이점: useRef 값은 변경되어도 렌더링되지 않는다. 주로 DOM 접근 또는 이전 값 추적 용도로 사용된다.
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(), [dependencies]);
- 첫 번째 인자: 비용이 큰 연산을 포함한 함수
- 두 번째 인자: 의존성 배열. 값이 변경되지 않으면 메모이징된 값 재사용
- 언제 쓰는가: 성능 최적화. 동일한 계산을 반복하지 않기 위해 사용된다.
- useCallback과의 차이점: useMemo는 값(결과)을 저장하고, useCallback은 함수 자체를 저장한다.
useCallback
const memoizedFn = useCallback(() => handleClick(), [dependencies]);
- 첫 번째 인자: 메모이징할 함수
- 두 번째 인자: 의존성 배열. 변경될 경우에만 함수 새로 생성
- 언제 쓰는가: props로 콜백 함수를 자식에게 전달해야 할 때, 또는 렌더링 방지를 위해 함수 참조 고정이 필요할 때
React Router
설치 및 구성
npm install react-router-dom
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
Link vs NavLink 차이점
- Link: 단순한 페이지 이동 용도. 스타일 적용이 필요하지 않을 때 사용
<Link to="/home">Home</Link>
- NavLink: 현재 경로가 일치하면 활성화 상태 클래스(active)를 자동 부여
<NavLink to="/home" className={({ isActive }) => isActive ? 'active' : ''}>Home</NavLink>
- 사용 예시: 네비게이션 바에서는 NavLink, 일반 버튼이나 아이콘 이동은 Link
동적 라우팅
<Route path="/user/:id" element={<User />} />
import { useParams } from 'react-router-dom';
function User() {
const { id } = useParams();
return <div>사용자 ID는 {id}입니다</div>;
}
고급 개념들
Suspense + Lazy
import { Suspense, lazy } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>로딩 중...</div>}>
<LazyComponent />
</Suspense>
);
}
- lazy: 컴포넌트를 동적으로 import하여 초기 로딩 속도 향상
- Suspense: lazy 컴포넌트가 로딩될 때 fallback UI를 보여준다
- 언제 쓰는가: 페이지 단위 코드 분할, 무거운 컴포넌트를 지연 로딩할 때
코드 스플리팅
- 무거운 컴포넌트를 React.lazy로 분할하여 필요할 때만 로딩함
- 초기 번들 크기를 줄이고 성능 최적화를 도모함
커스텀 훅 (Custom Hook)
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = () => setValue(v => !v);
return [value, toggle];
}
- 반복되는 로직을 추출하여 재사용성 향상
- 주요 예시: API 요청 훅, 입력 값 추적 훅, 로딩 상태 관리 훅 등
추가로 알면 좋은것들
- useState 대신 useReducer로 상태 로직을 명확히 할 수 있다.
- props 전달이 깊어질 경우 useContext로 전역 상태화하자.
- 렌더링 최적화를 위해 React.memo, useMemo, useCallback을 적극 활용하자.
- 복잡한 로직은 커스텀 훅으로 분리하여 유지보수를 용이하게 하자.
- 라우터는 반드시 BrowserRouter, Routes, Route 구조를 따르자.
페이지 vs 라우터
1. 라우터(Router)의 element는 어떤 컴포넌트를 해당 URL에 렌더링할지 지정하는 것
{
path: '/login',
element: <LoginPage />, // 이게 바로 컴포넌트야 (보통 "페이지" 컴포넌트를 연결)
}
2. "페이지(Page)"란?
- 페이지는 라우터에 직접 연결된 상위 컴포넌트를 말해.
- 즉, 주소(/login, /createPost)에 따라 바뀌는 큰 단위 컴포넌트!
/pages/LoginPage.jsx ✅ 페이지 컴포넌트
/pages/HomePage.jsx ✅ 페이지 컴포넌트
/components/PostCard.jsx ❌ 페이지 아님 → 그냥 재사용 컴포넌트
3. 라우터에 등록하는 건 "페이지 컴포넌트"만 하는 게 일반적
// ❌ 이렇게는 안 씀 (PostCard는 페이지가 아니니까)
{
path: '/postcard',
element: <PostCard />,
}
// ✅ 이렇게 씀
{
path: '/',
element: <HomePage />, // HomePage 안에서 PostCard를 불러다 씀
}
구조 예시
/src
├── pages/
│ ├── HomePage.jsx ← 페이지 (라우터에 연결)
│ ├── CreatePost.jsx ← 페이지 (라우터에 연결)
│ └── LoginPage.jsx ← 페이지 (라우터에 연결)
├── components/
│ ├── PostCard.jsx ← UI 컴포넌트 (페이지 내부에서 사용)
│ └── Header.jsx ← 공통 컴포넌트
구분 설명 예시
구분 | 설명 | 예시 |
페이지 컴포넌트 | 라우터에 등록되는 최상위 컴포넌트 | LoginPage, CreatePost |
일반 컴포넌트 | 여러 페이지에서 재사용하는 컴포넌트 | PostCard, Button, Input |
element | 라우터에서 어떤 컴포넌트를 띄울지 정하는 속성 | element: <LoginPage /> |
728x90
'💡 URECA > 🗒️ 스터디 노트' 카테고리의 다른 글
[URECA] Day 62 React Proj WalletWatcher (2) | 2025.04.25 |
---|---|
[URECA] Day 60 React Redux (0) | 2025.04.24 |
[URECA] Day58 React PROJ Shop URL (0) | 2025.04.22 |
[URECA] Day57 React Shop PROJ - CartPage, ShopPage (0) | 2025.04.21 |
[URECA] Day56 React PROJ SHOP (0) | 2025.04.18 |