728x90
반응형
✅ Vite로 자동 구성한 React App
Vite를 사용하여 React 애플리케이션을 자동으로 구성하는 과정에 대해 설명합니다. Vite는 빠르고 효율적인 개발 환경을 제공하는 도구로, 기본 설정이 적용된 React 앱을 쉽게 생성할 수 있습니다.
🔹 1. Vite
- 설명: Vite는 현대적인 웹 애플리케이션을 위한 빌드 도구로, 빠른 시작과 핫 모듈 교체(Hot Module Replacement, HMR)를 지원합니다.
- 명령어: 아래 명령어를 사용하여 Vite를 설치하고 새로운 React 애플리케이션을 생성합니다.
npm create vite@latest
🔹 2. 프레임워크 선택
- 설명: 애플리케이션의 프레임워크로 React를 선택합니다.
- 옵션: 설치 과정에서 react를 선택합니다.
🔹 3. 버전 선택
- 설명: JavaScript 또는 TypeScript 중 하나를 선택합니다.
- 옵션: 필요에 따라 TypeScript 또는 JavaScript를 선택합니다.
🔹 4. package.json의 라이브러리 설치
- 설명: 프로젝트의 종속성을 설치합니다.
- 명령어: 아래 명령어로 필요한 라이브러리를 설치합니다.
npm install
🔹 5. public 폴더
- 설명: public 폴더는 정적 파일을 보관하는 장소입니다.
- 예시 파일: vite.svg와 같은 정적 파일이 위치합니다.
🔹 6. src 폴더
- 설명: src 폴더는 동적 파일을 보관하는 장소입니다.
- 구성 요소:
- .jsx: JSX 구문을 사용하는 파일로, JavaScript 코드 내에 HTML을 포함할 수 있습니다.
- assets: 정적 자원을 프로젝트 코드에서 동적으로 사용하는 곳입니다.
✅ public 폴더와 assets 폴더의 차이
- public 폴더: 앱 빌드 후 직접적으로 접근할 수 있는 정적 파일들을 저장하는 곳입니다. index.html, favicon, 이미지 등과 같은 파일들이 여기에 포함됩니다. 브라우저에서 직접 접근이 가능합니다.
- assets 폴더: React 컴포넌트 내에서 사용되는 정적 파일들을 보관하는 곳입니다. 이 파일들은 빌드 후 자동으로 최적화되고, 코드 내에서 동적으로 참조됩니다 (예: 이미지, 폰트, 스타일시트 등).
- 결론: public은 "브라우저에서 직접 접근" 가능한 파일들을 위한 폴더이고, assets는 React 코드에서 참조하여 사용하는 파일들을 위한 폴더입니다.
🔹 7. .eslintrc.cjs
- 설명: ESLint 도구의 설정 파일로, 코드 스타일을 통일하고 코드 품질을 향상시키기 위해 사용됩니다.
🔹 8. .gitignore
- 설명: GitHub에 올릴 때 무시할 파일 목록을 정의합니다. 이 파일에는 node_modules/와 같은 자동 생성 파일들이 포함됩니다.
🔹 9. index.html
- 설명: 리액트 앱의 기본 틀을 제공하는 HTML 파일입니다. React 애플리케이션이 이 파일을 통해 DOM에 렌더링됩니다.
🔹 10. vite.config.js
- 설명: Vite의 옵션을 설정하는 파일입니다. 빌드와 개발 서버의 설정을 포함할 수 있습니다.
🔹 11. React App 실행
- 설명: React 애플리케이션을 실행하기 위한 명령어가 package.json의 scripts 부분에 정의되어 있습니다.
- 명령어: 아래 명령어로 애플리케이션을 실행합니다.
npm run dev
🔥 결론
Vite를 사용하여 자동으로 구성한 React 애플리케이션은 빠른 개발 환경과 효율적인 구조를 제공합니다. 각 파일과 폴더의 역할을 이해하고, 필요에 따라 커스터마이징함으로써 강력한 웹 애플리케이션을 개발할 수 있습니다! 🚀
✅ React App 구동 원리
React 애플리케이션의 구동 원리는 기본적으로 npm을 통한 개발 서버 실행과 React의 렌더링 메커니즘을 기반으로 합니다. 이를 통해 동적인 UI를 관리할 수 있습니다.
🔹 1. npm run dev 실행
- npm run dev 명령어를 통해 Vite 개발 서버를 실행합니다.
🔹 2. 리액트 내장 웹서버 구동
- 리액트 애플리케이션은 개발 서버를 통해 구동됩니다.
- 웹 서버는 인터넷 주소와 포트 주소로 구분되며, 일반적으로 localhost:3000 또는 localhost:5173에서 접근할 수 있습니다.
🔹 3. 렌더링 원리
- React는 index.html 파일의 스크립트 부분을 통해 동적인 UI를 관리합니다.
- 주요 스크립트 파일은 /src/main.jsx입니다.
🔹 4. main.jsx 파일
- main.jsx 파일은 React 앱의 진입점으로, ReactDOM의 메서드를 사용하여 컴포넌트를 렌더링합니다.
✅ 내부 메서드
React 앱 구동의 핵심 내부 메서드에는 여러 가지가 있으며, 그 중에서 자주 사용되는 메서드를 설명합니다:
- ReactDOM.render()
- React 컴포넌트를 HTML에 렌더링합니다. index.html에 정의된 특정 div나 다른 DOM 요소에 React 컴포넌트를 삽입합니다.
- 예시:
ReactDOM.render(<App />, document.getElementById('root'));
- useState()
- 컴포넌트 내에서 상태를 관리할 때 사용됩니다. 상태가 변경되면 컴포넌트가 재렌더링됩니다.
- 예시:
const [count, setCount] = useState(0);
- useEffect()
- 컴포넌트가 렌더링된 후 특정 작업을 실행하는 데 사용됩니다. 주로 API 요청, 구독 등을 처리할 때 사용됩니다.
- 예시:
useEffect(() => { console.log('컴포넌트가 렌더링되었습니다!'); }, []);
이 메서드들은 React의 상태 관리, 렌더링, 그리고 라이프사이클 관리에서 중요한 역할을 합니다.
✅ createRoot()
- createRoot()는 React 18에서 도입된 메서드로, React 앱을 DOM에 렌더링하는 새로운 방법입니다. React 17까지는 ReactDOM.render()를 사용했지만, createRoot()는 더 효율적이고 향상된 성능을 제공합니다.
- 이를 통해 앱을 렌더링할 루트를 생성하고, 해당 루트에 컴포넌트를 렌더링합니다.
- 예시:
import ReactDOM from 'react-dom/client'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);
- createRoot()는 자동으로 최신 React 기능(예: Concurrent Mode)을 지원합니다.
🔹 5. App.jsx 파일
✅ App.jsx의 역할
- UI의 시작점: React 애플리케이션에서 기본적인 UI를 정의하는 컴포넌트입니다.
- 상태 관리: 애플리케이션의 상태를 useState와 같은 훅을 사용하여 관리합니다.
- 컴포넌트 렌더링: 다른 컴포넌트를 렌더링하거나 UI를 동적으로 업데이트하는 역할을 합니다.
✅ 실행 순서
- React 앱 초기화: Vite로 빌드된 애플리케이션이 실행되면 index.html에서 App.jsx가 호출됩니다.
- 상태 설정 및 초기 렌더링: useState로 초기 상태를 설정하고 UI를 렌더링합니다.
- 상태 변경 시 리렌더링: 상태가 변경되면 컴포넌트가 다시 렌더링되어 UI가 업데이트됩니다.
✅ 동작 원리
- 컴포넌트 함수: App.jsx는 함수형 컴포넌트로서 JSX를 반환하고, React가 이를 화면에 그립니다.
- 상태 변화 감지: useState와 같은 훅을 사용하여 상태 변화에 따라 화면을 자동으로 리렌더링합니다.
- 이벤트 처리: 버튼 클릭 등 사용자 상호작용에 따라 상태를 변경하고, 이를 화면에 반영합니다.
✅ 특징
- 함수형 컴포넌트: React에서 권장하는 최신 컴포넌트 작성 방식입니다.
- JSX: JavaScript 내에서 HTML-like 문법을 사용하여 UI를 정의합니다.
- 동적 UI: 상태 관리와 이벤트 처리를 통해 UI를 동적으로 변경할 수 있습니다.
✅ 관련 문법
- useState: 상태를 관리하는 React 훅.
const [count, setCount] = useState(0);
- JSX 반환: HTML처럼 보이지만 실제로는 JavaScript 코드입니다.
return <div><h1>Welcome</h1></div>;
- 이벤트 처리: React에서는 이벤트 핸들러를 통해 상태를 변경하고 UI를 갱신합니다.
<button onClick={() => setCount(count + 1)}>Increment</button>
✅ 예제 코드
import React, { useState } from 'react'; // React와 useState 훅을 가져옴
function App() { // App 컴포넌트를 함수형 컴포넌트로 정의
const [count, setCount] = useState(0); // 상태 변수 `count`와 상태 변경 함수 `setCount`를 선언, 초기값은 0
return ( // JSX 문법으로 UI 반환
<div>
<p>{count}</p> // 상태 값 `count`를 화면에 출력
<button onClick={() => setCount(count + 1)}>Increment</button> // 버튼 클릭 시 `count` 값 증가
</div>
);
}
export default App; // 다른 파일에서 이 컴포넌트를 사용할 수 있게 내보냄
🔹 6. React 앱 구동 흐름
- index.html에서 스크립트 로드:
- index.html에는 기본적인 HTML 구조와 <div id="root"></div> 요소가 포함되어 있습니다. 이 root div는 React 앱이 렌더링될 대상입니다.
- <script type="module" src="/src/main.jsx"></script> 태그를 통해 React 앱의 엔트리 포인트인 main.jsx 파일을 로드합니다.
- main.jsx 실행:
- main.jsx 파일에서는 ReactDOM.createRoot()를 사용하여 root div에 React 컴포넌트를 렌더링합니다.
- createRoot()는 root 요소를 React의 "root"로 지정하고, 해당 요소에 렌더링을 시작합니다.
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App';
root.render(); - App.jsx 컴포넌트 렌더링:
- App.jsx 파일에서는 JSX 문법을 사용하여 UI를 정의하고, 이 JSX가 실제 DOM으로 변환되어 렌더링됩니다.
- React는 App.jsx 컴포넌트를 렌더링하고, 그 결과는 root div에 표시됩니다. React는 상태 관리(useState, useEffect 등)를 통해 동적으로 UI를 업데이트합니다.
- 최종 UI 표시:
- React는 App.jsx에서 반환된 JSX를 가상 DOM에 반영하고, 이를 실제 DOM에 반영합니다. 이 과정에서 UI가 브라우저에 렌더링되고 사용자가 화면을 볼 수 있게 됩니다.
🔥 결론
- React 앱의 구동 원리는 Vite와 React의 내장 메서드를 통해 이루어집니다.
- 이 구조를 통해 개발자는 효율적으로 동적인 UI를 구성하고 관리할 수 있습니다. 🚀
✅ 리액트 훅을 사용한 할 일 목록 및 사용자 정보 관리 애플리케이션
이 예제는 React의 여러 훅을 활용하여 상태 관리, 비동기 데이터 처리 및 성능 최적화를 시뮬레이션합니다.
🔹 1. 전체 흐름
- MainApp에서 UserContext.Provider가 App 컴포넌트를 감싸며 사용자 정보를 제공합니다.
- App 컴포넌트:
- useState로 카운트를 관리합니다.
- useReducer로 할 일 목록과 로딩 상태를 관리합니다.
- useMemo로 계산된 값을 최적화합니다.
- useCallback으로 handleClick 함수를 메모이제이션합니다.
- useEffect로 비동기적으로 데이터를 가져와 todos 상태를 업데이트합니다.
- useContext로 사용자 정보를 전역에서 가져옵니다.
🔹 2. 코드 예시
import React, { useState, useEffect, useMemo, useCallback, useContext, useReducer } from 'react';
// 사용자 정보를 위한 Context 생성
const UserContext = React.createContext();
// useReducer로 상태 관리하는 예시 (할 일 상태 관리)
const initialState = { todos: [], loading: true };
// 리듀서 함수 정의
function reducer(state, action) {
switch (action.type) {
case 'SET_TODOS':
return { ...state, todos: action.payload, loading: false };
default:
return state;
}
}
function App() {
// 1. useState로 상태 관리 (카운트)
const [count, setCount] = useState(0);
// 2. useReducer로 복잡한 상태 관리 (할 일 목록)
const [state, dispatch] = useReducer(reducer, initialState);
// 3. useMemo로 계산 비용이 큰 값 메모이제이션
const expensiveCalculation = useMemo(() => {
console.log('계산 중...');
return count * 2; // 예시로 계산 비용이 큰 작업
}, [count]);
// 4. useCallback으로 함수 메모이제이션
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
// 5. useEffect로 비동기 작업 (API 호출 시뮬레이션)
useEffect(() => {
// 2초 후에 할 일 목록을 가져오는 비동기 작업
setTimeout(() => {
dispatch({ type: 'SET_TODOS', payload: [{ id: 1, task: 'React 공부' }, { id: 2, task: '앱 만들기' }] });
}, 2000);
}, []);
// 6. useContext로 Context 값 사용 (사용자 정보)
const user = useContext(UserContext);
return (
<div>
<h1>{user.name}의 할 일 목록</h1>
<button onClick={handleClick}>Count: {count}</button>
<p>계산된 값: {expensiveCalculation}</p>
{state.loading ? (
<p>Loading...</p>
) : (
<ul>
{state.todos.map(todo => (
<li key={todo.id}>{todo.task}</li>
))}
</ul>
)}
</div>
);
}
// App 컴포넌트 내에서 Context 제공
export default function MainApp() {
return (
<UserContext.Provider value={{ name: '홍길동' }}>
<App />
</UserContext.Provider>
);
}
🔹 3. 주요 동작
- 초기 렌더링:
- count와 todos 상태가 초기화됩니다.
- useEffect가 실행되어 todos를 비동기적으로 받아옵니다.
- loading 상태가 true로 설정되어 "Loading..."이 출력됩니다.
- 비동기 API 호출:
- 2초 후, todos 상태를 업데이트하며 loading 상태가 false로 변경됩니다.
- 성능 최적화:
- useMemo는 count가 변경될 때만 재계산합니다.
- useCallback은 handleClick 함수가 불필요하게 재생성되는 것을 방지합니다.
- 전역 상태 관리:
- UserContext.Provider가 App에 사용자 정보를 제공하고, useContext로 해당 정보를 사용합니다.
🔥 결론
- 리액트 훅을 사용하여 상태와 부수 효과를 관리하고, 성능을 최적화할 수 있습니다. 각 훅의 사용과 실행 순서를 이해하는 것이 중요합니다.
훅역할특징사용미사용실행 순서
useState | 상태 관리 | 컴포넌트 내에서 로컬 상태를 관리 | 간단한 상태 관리 (예: 카운터) | 상태 로직이 복잡한 경우 | 1. 초기 상태 값 설정 2. 상태 업데이트 시 리렌더링 |
useEffect | 생명 주기 처리 | 특정 조건에 따라 부수 효과 실행 | API 호출, 타이머 설정 등 | 의존성 배열을 잘못 설정할 경우 | 1. 컴포넌트 마운트 후 실행 2. 의존성 변경 시 실행 |
useMemo | 계산 최적화 | 값의 계산을 메모이제이션하여 성능 최적화 | 계산 비용이 큰 값의 재계산 필요 | 자주 변경되는 값에 사용 시 비효율 | 1. 의존성 배열 변경 시 재계산 2. 메모이제이션된 값 반환 |
useCallback | 함수 메모이제이션 | 불필요한 함수 재생성 방지 | 자식 컴포넌트에 콜백 전달 시 | 의존성이 자주 변경될 경우 | 1. 의존성 배열 변경 시 함수 재생성 2. 메모이제이션된 함수 반환 |
useContext | 전역 상태 관리 | Context API를 통해 상위 컴포넌트의 값 전달 | 여러 컴포넌트에서 데이터 공유 시 | 상태가 간단한 경우 | 1. 최상위 컴포넌트에서 Provider로 값 전달 2. 하위 컴포넌트에서 useContext로 값 사용 |
useReducer | 복잡한 상태 관리 | 복잡한 상태와 로직을 한 곳에서 관리 | 여러 액션에 따라 복잡한 상태 변화 | 상태가 간단한 경우 | 1. 초기 상태 설정 2. 액션 디스패치로 상태 업데이트 |
728x90
반응형
'JavaScript > React.js' 카테고리의 다른 글
1. 리액트 기술적 특징 (0) | 2025.01.13 |
---|---|
리액트 공부하기 (0) | 2025.01.13 |