일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 캡슐화
- webdevelopment
- 불변성
- 웹개발
- 타입스크립트
- 패스트캠퍼스
- 논리연산자
- OOP
- Hooks
- REACT
- 프론트엔드
- 노마드코더
- frontend
- typeScript
- 리액트
- Zustand
- 클래스
- 객체지향프로그래밍
- CSS
- 부트캠프
- Props
- github
- 추상화
- 자바스크립트
- 자바스트립트
- Fetch
- 투두앱만들기
- 상속
- js
- JavaScript
- Today
- Total
connecting dots
React | React Hooks - useState와 UseEffect, 마운트(Mount)와 렌더링(Rendering), 호이스팅(Hoisting), 컴포넌트(Component)와 라이브러리(Library) 본문
React | React Hooks - useState와 UseEffect, 마운트(Mount)와 렌더링(Rendering), 호이스팅(Hoisting), 컴포넌트(Component)와 라이브러리(Library)
dearsuhyun 2024. 7. 25. 19:33useState와 UseEffect
useState와 useEffect는 React 훅으로, 각각 상태(state)와 사이드 이펙트(side effect)를 관리하는 데 사용됩니다.
1. useState
useState는 함수 컴포넌트에서 상태를 관리하기 위해 사용됩니다.
이는 컴포넌트가 상태를 가지고 있고, 이 상태가 변경될 때 컴포넌트를 다시 렌더링할 수 있게 합니다.
예제
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 상태 변수와 그 상태를 변경하는 함수
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
export default Counter;
사용 방법
1) 초기화: useState는 초기 상태 값을 인수로 받습니다. 예를 들어, useState(0)는 초기 상태를 0으로 설정합니다.
2) 상태 변수와 업데이트 함수: useState는 배열을 반환하며, 첫 번째 요소는 현재 상태 값, 두 번째 요소는 상태를 업데이트하는 함수입니다.
3) 상태 업데이트: 상태 업데이트 함수(setCount 등)를 호출하면 React는 컴포넌트를 다시 렌더링합니다.
2. useEffect
useEffect는 함수 컴포넌트에서 사이드 이펙트를 수행하기 위해 사용됩니다. 이는 컴포넌트가 렌더링될 때나 특정 상태가 변경될 때 실행하고 싶은 코드(예: 데이터 가져오기, 구독, DOM 업데이트 등)를 포함할 수 있습니다.
cf. 사이드 이펙트란 ?
함수가 자신의 범위를 벗어나 외부 상태를 변경하거나, 외부 시스템과 상호작용하는 것.
ex. API 호출, 콘솔 출력, DOM 조작, 파일 읽기/쓰기 등.
copilot said ...
비유: 방 청소
• 주요 작업: 방 청소
• 사이드 이펙트: 간식 먹기
-> 청소를 하다가 갑자기 냉장고에서 간식을 꺼내 먹는다면, 이것이 바로 사이드 이펙트야. 왜냐하면 청소와는 직접적인 관련이 없는 일이기 때문이지.
프로그래밍에서의 사이드 이펙트
프로그래밍에서 사이드 이펙트는 함수가 자신의 주요 작업 외에 다른 일을 하는 것을 말해요. 이 다른 일이 코드의 다른 부분에 영향을 줄 수 있어요.
function App() { const [users, setUsers] = useState([]); useEffect(() => { getUsers(); }, []); async function getUsers() { const res = await fetch('https://api.heropy.dev/v0/users'); const data = await res.json(); console.log('응답결과: ', data); setUsers(data.users); }
이 예제에서 App 컴포넌트의 원래 역할은 유저 목록을 렌더링 하는 것입니다.
useEffect 내부에서 getUsers를 호출하여 데이터를 가져오는 작업은 컴포넌트의 렌더링과 직접적인 관련이 없는 작업입니다. 이 작업이 사이드 이펙트에 해당합니다.
예제
import { useState, useEffect } from 'react'
useEffect(() => {
getUsers()
}, [])
async function getUsers() {
const res = await fetch('https://api.heropy.dev/v0/users')
const data = await res.json()
console.log('응답결과: ', data)
setUsers(data.users)
}
return (
<>
<ul>
{users.map(user => (
<li key={user.name}>{user.name}</li>
))}
</ul>
</>
)
useEffect 훅 내부에서 setUsers를 호출하여 상태를 업데이트 합니다.
이를 통해 컴포넌트가 처음 렌더링 될 때 데이터를 가져오고, 그 데이터를 상태로 저장하여 화면에 표시합니다.
setUsers(data.users) --> 가져온 사용자 데이터를 users 상태로 설정하는 함수 (users = 사용자 목록을 저장하는 상태)
setUsers가 호출되어 users 상태가 업데이트되면 React는 컴포넌트를 다시 렌더링합니다.
새로운 users 상태를 기반으로 사용자 목록이 화면에 표시됩니다.
마운트(Mount)와 렌더링(Rendering)
1. 마운트(Mount)
마운트는 컴포넌트가 처음으로 DOM에 삽입될 때 발생하는 과정입니다.
마운트는 컴포넌트의 생명주기에서 가장 처음 일어나는 단계입니다.
• 처음 DOM에 추가될 때: 컴포넌트가 처음 생성되어 DOM 트리에 추가되는 순간입니다.
• 초기화: 이 단계에서는 컴포넌트의 상태가 초기화되고, 필요한 초기 데이터가 로드됩니다.
2. 렌더링(Rendering)
렌더링은 컴포넌트가 DOM에 어떤 내용을 표시할지를 결정하고, 이를 실제로 화면에 그리는 과정입니다.
렌더링은 컴포넌트가 처음 마운트될 때와 상태 또는 속성이 변경될 때마다 발생합니다.
• 초기 렌더링: 컴포넌트가 처음 마운트될 때 발생하는 렌더링입니다.
• 재렌더링: 상태(state)나 속성(props)이 변경될 때 발생하는 렌더링입니다.
==>
마운트는 컴포넌트가 처음으로 DOM에 삽입될 때 발생하는 과정으로, 초기화 작업이 이루어집니다.
렌더링은 컴포넌트가 화면에 표시될 내용을 결정하고, 이를 실제로 그리는 과정으로, 초기 렌더링과 재렌더링이 포함됩니다.
호이스팅(Hoisting)
호이스팅은 JavaScript의 기본 동작 방식 중 하나로, 변수와 함수 선언이 실제 코드가 실행되기 전에 끌어올려지는 것처럼 동작하는 현상입니다. React에서도 JavaScript의 이러한 호이스팅 동작이 동일하게 적용됩니다.
1. React 컴포넌트에서 변수 호이스팅
let과 const로 선언된 변수는 호이스팅되지만, 초기화 전에 접근하려고 하면 ReferenceError가 발생합니다.
- 예제
import React from 'react';
function MyComponent() {
console.log(message); // ReferenceError: Cannot access 'message' before initialization
let message = 'Hello, World!'; // 변수 초기화
console.log(message); // 'Hello, World!'
return <div>{message}</div>;
}
export default MyComponent;
cf. 초기화가 일어나는 이유 ?
초기화가 일어나는 이유를 이해하려면 JavaScript에서 변수 선언과 초기화의 동작 방식을 살펴봐야 합니다. JavaScript 엔진은 코드를 실행하기 전에 변수를 선언하고 초기화하는 단계를 거칩니다. 이 과정은 두 단계로 나뉩니다.
변수 선언(Declaration)과 변수 초기화(Initialization).
let과 const로 선언된 변수는 선언이 끌어올려지지만, 초기화는 변수 선언 위치에서 이루어집니다. 초기화 전에 변수를 참조하려고 하면 ReferenceError가 발생합니다. 이는 일종의 “일시적 사각 지대(Temporal Dead Zone, TDZ)” 때문입니다.
위 코드 변환 모습
let message; // 선언이 호이스팅됨, 초기화되지 않음 (TDZ)
console.log(message); // ReferenceError: Cannot access 'message' before initialization
message = 'Hello, World!'; // 초기화
console.log(message); // 'Hello, World!'
변수 선언: let message;가 함수의 최상단으로 끌어올려집니다.
TDZ: 선언된 변수는 초기화되기 전까지 “일시적 사각 지대”에 있습니다. 초기화 전에 접근하면 ReferenceError가 발생합니다.
변수 초기화: 실제 코드 위치에서 변수에 값이 할당됩니다(message = 'Hello, World!';).
copilot said ...
TDZ(일시적 사각지대)란 ?
비유: 방에 있는 물건 찾기
1. 방의 물건 준비:
• 방에 새로운 물건(예: 책)을 놓기로 했습니다.
• 물건을 방에 놓기 전에 방에 들어가서 물건을 찾으려고 하면, 물건이 아직 방에 없기 때문에 찾을 수 없습니다.
2. 물건 놓기:
• 이제 방에 책을 놓습니다.
• 책을 놓은 후에는 언제든지 방에 들어가서 책을 찾을 수 있습니다.
// 책을 방에 놓기 전에 찾으려고 하는 상황 console.log(book); // ReferenceError: Cannot access 'book' before initialization let book = 'JavaScript Book'; console.log(book); // 'JavaScript Book'
단계별 설명
1. 변수 선언 (방에 물건 놓기로 결정):
• let book이라는 변수를 선언합니다.
• 이 시점부터 TDZ가 시작됩니다. (물건을 방에 놓기 전)
2. TDZ (일시적 사각지대):
• let book이 선언된 이후 초기화되기 전까지의 구간입니다.
• 이 기간 동안 book에 접근하면 오류가 발생합니다. (방에 들어가서 물건을 찾으려고 하지만, 아직 물건이 방에 없음)
3. 변수 초기화 (물건을 방에 놓기):
• book = 'JavaScript Book'에서 변수 초기화가 이루어집니다.
• 이제 book 변수는 사용할 준비가 되었습니다. (물건이 방에 놓임)
4. 초기화 후 접근 (물건을 방에서 찾기):
• 초기화가 완료된 후에는 book 변수에 정상적으로 접근할 수 있습니다.
• 이제 console.log(book)는 ‘JavaScript Book’을 출력합니다. (방에 들어가서 물건을 찾을 수 있음)
2. React 컴포넌트에서 함수 호이스팅
import React from 'react';
function MyComponent() {
console.log(greet()); // Hello, World!
function greet() {
return 'Hello, World!';
}
return <div>{greet()}</div>;
}
export default MyComponent;
위 코드에서 greet 함수는 호이스팅되어 함수의 최상단으로 끌어올려지기 때문에 함수 호출이 선언문보다 앞에 있어도 정상적으로 동작합니다.
3. React 훅에서 함수 호이스팅
React 훅에서의 호이스팅은 일반적인 JavaScript의 호이스팅과는 조금 다릅니다. React 훅(useState, useEffect 등)은 반드시 컴포넌트의 최상위 레벨에서 호출되어야 합니다. 그렇지 않으면, 훅이 조건문이나 반복문 내에서 호출되었을 때, 훅의 호출 순서가 변경될 수 있기 때문에 React가 상태를 제대로 관리할 수 없습니다.
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0); // 최상위에서 호출
const [name, setName] = useState('Alice'); // 최상위에서 호출
useEffect(() => {
console.log(`Component mounted with name: ${name}`);
}, [name]); // 최상위에서 호출
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
export default MyComponent;
컴포넌트(Component)와 라이브러리(Library)
컴포넌트 | 라이브러리 | |
의미 | 큰 프로그램을 구성하는 작은 부품 독립적이고 재사용 가능한 코드 조각 |
특정 기능을 쉽게 구현할 수 있도록 미리 작성된 코드의 모음 개발자는 필요한 기능을 직접 작성하는 대신, 라이브러리에서 제공하는 코드를 가져다 사용 |
예시 | 웹 페이지에서 헤더, 푸터, 버튼, 리스트 등 각각의 요소 |
jQuery, Lodash, React Router |
비유 | 레고 블록 하나하나 여러 레고 블록을 조립하여 하나의 완성된 작품(프로그램)을 만들 수 있 |
레고 설명서 레고 블록을 조립할 때, 설명서에 따라 쉽게 조립할 수 있는 것처럼, 라이브러리는 개발자가 코드를 작성할 때 필요한 기능을 쉽게 구현할 수 있도록 도와줌 |
'TIL' 카테고리의 다른 글
자바스크립트의 실행 컨텍스트(Execution Context)와 this 키워드, ES6 모듈 특징 (0) | 2024.08.21 |
---|---|
Javascript | 생성자 함수(prototype), this, ES6 Class, 상속 (0) | 2024.08.03 |
JS | 객체지향 프로그래밍 (Object Oriented Programming) 이해하기 - class, this, constructor, 추상화, 상속, super, 캡슐화, 객체와 인스턴스 (0) | 2024.07.28 |
CSS | css와 module.css의 차이점 (0) | 2024.07.27 |
JS | Array method(배열 메소드) 정리 (4) | 2024.07.25 |