※체크 리스트
① 함수형 컴포넌트의 개념과 특징, 이해
② 함수형 컴포넌트를 사용해 React 애플리케이션을 작성하기
③ useState와 useEffect를 활용해 동적인 UI 구현하기
1. React의 함수형 컴포넌트
1-1. 정의
JavaScript 함수로 정의되는 React 컴포넌트
클래스형 컴포넌트와 달리 React의 Component를 상속받지 않으며 단순한 함수로 동작한다
1-2. 특징
① 간결함 : 구조가 간단하고 코드 작성이 쉽다
② 무상태(Stateless) : 초기에는 상태를 관리하지 않았으나, React Hooks 도입 이후 상태와 생명주기를 관리할 수 있게 됬다
③ 성능 최적화 : 클래스형 컴포넌트보다 메모리 사용량이 적고 렌더링 속도가 빠르다
1-3. 함수형 컴포넌트와 클래스형 컴포넌트 비교
함수형 컴포넌트 | 클래스형 컴포넌트 | |
작성 방식 | JavaScript 함수 | React.Component를 상속받는 클래스 |
상태 관리 | useState Hook 사용 | this.state 사용 |
라이프사이클 관리 | useEffect Hook 사용 | 라이프사이클 메소드 사용 |
코드 가독성 | 간결하고 직관적 | 상대적으로 복잡 |
2. 함수형 컴포넌트 작성
1, 2, 3 단계로 진행하며 프로젝트를 만들어 설명하려 한다
1) React 프로젝트 생성
npx create-react-app functional-component-app
2) 프로젝트 만들 구조
src/
├── components/
│ ├── Greeting.js // 1단계, 2단계 코드
│ ├── Counter.js // 3단계 코드
├── App.js // 컴포넌트들을 연결하는 메인 파일
├── index.js // 기본 엔트리 포인트
3) 1단계 : 기본 함수형 컴포넌트 작성
① React 함수형 컴포넌트는 단순한 함수를 반환한다
> Greeting.js
// src/components/Greeting.js
// 1단계 기본함수형 컴포넌트
function Greeting() {
return <h1>Hello, React!</h1>;
}
export default Greeting;
② Greeting 컴포넌트를 App 컴포넌트에서 사용
> App.js
// src/App.js
import React from 'react';
import Greeting from './components/Greeting';
// 1단계 기본 함수형 컴포넌트
function App() {
return (
<div>
<Greeting />
</div>
);
}
export default App;
③ 실행
npm start
4) 2단계 : Props 사용
① > Greeting.js
// src/components/Greeting.js
// 1단계 기본 함수형 컴포넌트
/*
function Greeting() {
return <h1>Hello, React!</h1>
}
*/
// 2단계 Props 사용
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
export default Greeting;
② > App.js
// src/App.js
import React from 'react';
import Greeting from './components/Greeting';
// 1단계 기본 함수형 컴포넌트
/*
function App() {
return (
<div>
<Greeting />
</div>
)
}
*/
//2단계 Props 사용
function App() {
return <Greeting name="React!" />;
}
export default App;
③ 실행 결과
5) 3단계 : State 사용(React Hooks)
useState Hook을 사용해 상태를 관리합니다
① > Counter.js 생성
// src/components/Counter.js
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트 : {count}</p>
<button onClick={() => setCount(count+1)}>증가</button>
</div>
);
}
export default Counter;
② > App.js
// src/App.js
import React from 'react';
import Greeting from './components/Greeting';
import Counter from './components/Counter';
// 1단계 기본 함수형 컴포넌트
/*
function App() {
return (
<div>
<Greeting />
</div>
)
}
*/
// 2단계 Props 사용
/*
function App() {
return <Greeting name="React!" />;
}
*/
// 3단계 React Hook 사용 - useState
function App() {
return(
<div>
<Greeting name="React!" />
<Counter />
</div>
);
}
export default App;
③ 실행
3. 함수형 컴포넌트에서 생명주기 관리
☞ React 함수형 컴포넌트에서 useEffect를 사용하는 3가지 주요 시점
3-1. 컴포넌트가 마운트될 때 실행
1) 코드 작성
// src/App.js
import React, { useEffect } from 'react';
function App() {
useEffect(() => {
console.log("컴포넌트가 마운트되었습니다.")
}, []);
return <h1>Hello, React!</h1>;
}
export default App;
2) 설명
● useEffect의 두번째 인자에 빈 배열([ ])을 전달하면 이 useEffect는 컴포넌트가 마운트될 때 한번만 실행된다
● 주로 초기화 작업(데이터 fetch, 이벤트 리스터 등록 등)에 사용된다
3-2. 상태(State) 변경시 실행
1) 코드 작성
// src/components/Counter.js
import React, { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('카운트가 ${count}로 변경되었습니다.');
}, [count]); // count 상태가 변경될 때마다 실행
return(
<div>
<p>현재 카운트 : {count}</p>
<button onClick={() => setCount(count+1)}>증가</button>
</div>
);
}
export default Counter;
2) 설명
● useEffect의 두번째 인자로 배열( [count] )를 전달하면 배열 안에 있는 값이 변경될 때마다 useEffect가 실행된다
● 이 코드에서는 count 상태가 변경될 때마다 console.log로 새로운 값이 출력된다
● 주로 상태가 변경될 때 부수적인 작업 (예 : DOM 업데이트, API 호출, 로그 기록 등)에 사용된다
3-3. 컴포넌트가 언마운트될 때 실행
1) 코드 작성
useEffect(() => {
const interval = setInterval(() => {
console.log("타이머 동작 중");
}, 1000); // 1초마다 "타이머 동작 중" 로그 출력
return () => {
clearInterval(interval); // 언마운트 시 타이머 제거
console.log("컴포넌트가 언마운트되었습니다.");
};
}, []); // 빈 배열 : 마운트와 언마운트 시점에서만 실행
2) 설명
● useEffect 안에서 return문에 함수를 작성하면 해당 함수는 컴포넌트가 언마운트될 때 실행된다
● 위 코드에서 타이머(setInterval)를 설정하고 컴포넌트가 언마운트될 때 이를 제거(clearInterval)하며 로그를 출력한다
● 주로 정리(clean-up) 작업(이벤트 리스너 제거, 타이머 정리, 비동기 작업 취소 등)에 사용된다
▷ 정리
React의 함수형 컴포넌트에서 useEffect는 3가지 주요 시점에서 동작한다
① 마운트 : 빈 배열 [ ] → 한 번만 실행(초기화 작업)
② 상태/props 변경 : 배열에 의존성 전달 [state/props] → 해당 값 변경 시 실행
③ 언마운트 : return 안의 함수 → 정리(clean-up) 작업
4. 실습
▷ 사용자 입력을 받아 "안녕하세요, [사용자 이름]" 메시지를 표시하는 함수형 컴포넌트를 작성하세요
▷ 버튼 클릭 시 카운트를 증가시키고 10이상이 되면 "최대 카운트 도달" 메시지를 표시하세요
1) 구현
▷프로젝트 구조
Greeting.js : 사용자 입력 및 환영 메시지 표시
Counter.js : 버튼 클릭 시 카운트 증가 및 조건에 따른 메시지 표시
App.js : 두 가지 컴포넌트를 통합하여 화면에 표시
▷ 프로젝트 생성
npx create-react-app functional-component-practice
▷코드
① 사용자 입력을 받아 "안녕하세요, [사용자 이름]"을 표시하는 함수형 컴포넌트 만들기
> components/Greeting.js
// src/components/Greeting.js
import React, { useState } from 'react';
function Greeting() {
const [name, setName] = useState('');
return(
<div>
<input
type="text"
placeholder="이름을 입력하세요"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<h1>안녕하세요, {name}!</h1>
</div>
);
}
export default Greeting;
● useState를 사용해 name를 생성해 입력값(input)과 동기화한다
초기값 : 빈 문자열(' ')
상태 업데이트 함수 : setName
● <input> 태그로 사용자 입력을 받아, 입력값이 변경되면 onChange 이벤트를 통해 setName을 호출하여 name 상태를 업데이트 한다
☞ 사용자가 입력 창에 값을 입력하면 onChange 이벤트 발생 → name 상태 업데이트 → <h1> 태그 안의 내용 변경
② 증가 버튼 클릭 시 카운트를 증가시키고, 숫자가 10 이상이 되면 "최대 카운트 도달"을 표시하기
> src/components/Counter.js
// src/components/Counter.js
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트 : {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
{count >= 10 && <p style={{ color:'red' }}>최대 카운트 도달</p>}
</div>
);
}
export default Counter;
● useState 사용 : count 상태를 생성하여 버튼 클릭으로 증가시키는 카운트 값을 관리한다
● 조건부 렌더링 (&&) : count >= 10 조건이 참일때만 <p> 태그를 렌더링해 "최대 카운트 도달" 메시지 표시
☞ 버튼 클릭 → onClick 이벤트 발생 → count 값 증가 → 화면에 새로운 카운트 값과 조건부 메시지 업데이트
③ App.js에 컴포넌트 두개를 통합해 화면에 표시
> src/App.js
// src/App.js
import React from 'react';
import Greeting from './components/Greeting';
import Counter from './components/Counter';
function App() {
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<Greeting />
<hr />
<Counter />
</div>
);
}
export default App;
● Greeting 컴포넌트 렌더링 : 사용자가 이름을 입력하고 환영 메시지를 표시
● Counter 컴포넌트 렌더링 : 버튼 클릭으로 카운트를 증가시키고 메시지를 표시
☞ App 컴포넌트가 렌더링 → Greeting과 Counter 컴포넌트를 각각 렌더링 → 사용자의 입력/버튼 클릭에 따라 각 컴포넌트가 독립적으로 작동
2) 실행
※ 정리
① 함수형 컴포넌트와 클래스형 컴포넌트 중 어떤 것을 사용해야 할까요?
→ React의 최신 동향을 고려했을 때 함수형 컴포넌트를 사용하는게 일반적으로 더 권장된다
→ class를 사용할 필요가 없으므로 코드가 간결하고 읽기 쉬운 장점이 있다
→ useState, useEffect 등 React Hook을 사용해 복잡한 로직을 깔끔하게 구현할 수 있다
② useEffect의 의존성 배열은 어떻게 작동하나요?
→ 의존성 배열 : useEffect에서 두 번째 인자로 전달되는 배열이며 효과가 실행되는 조건을 결정한다
→ [ ] 빈 배열 : useEffect가 마운트될 때 한 번만 실행된다
useEffect(() => {
console.log("컴포넌트가 마운트되었습니다.");
}, []); // 빈 배열 : 마운트 시점에만 실행
→ [value] 값이 포함된 배열 : 배열에 명시된 값이 변경될 때마다 useEffect가 실행된다
useEffect(() => {
console.log('값이 변경되었습니다: ${count}');
}, [count]); //count가 변경될 때만 실행
→ 의존성 배열이 없는 경우 : useEffect가 모든 렌더링마다 실행되서 의도치 않은 성능 문제를 유발할 수 있으니 주의가 필요하다
useEffect(() => {
console.log("매 렌더링마다 실행됩니다");
}); // 의존성 배열 없음
'개발 기록 > front - react' 카테고리의 다른 글
React에서 Hook이란? (공부 + 면접 답변용) (1) | 2024.12.18 |
---|---|
React Query로 서버 상태 관리하기 : 데이터 패칭과 캐싱 (0) | 2024.12.17 |
[React] React 컴포넌트 생명주기, 생명주기 메소드 (0) | 2024.11.26 |
[react] React 컴포넌트와 Props, State (1) | 2024.11.25 |
[JavaScript] 화살표 함수 = (arrow function) => {} (2) | 2024.11.20 |