ddodoi 님의 블로그
11주차-파트04: 컴포넌트, state, hook, 구조분해할당, type, useState, map 본문
CHAPTER 1. 컴포넌트
✅컴포넌트
리액트에서 컴포넌트는 UI를 구성하는 재사용 가능한 코드 조각을 말한다(마치 레고 조각처럼). 리액트에서는 애플리케이션의 각 부분을 독립적이고, 자율적으로 관리할 수 있는 작은 컴포넌트들로 나눈다.
리액트의 컴포넌트에는 1) 클래스형 컴포넌트 2) 함수형 컴포넌트 가 있다.
1) 클래스형 컴포넌트
리액트에서는 클래스형 컴포넌트를 만들때 반드시 Component라는 클래스를 상속해야 한다. 그래서 Component를 import해야한다. ClassCom클래스 옆의 extends는 상속한단 의미이다. 반드시 render함수를 써야한다.
클래스형 컴포넌트 실습을 위해 새로운 파일 ClassCom.tsx를 만들어보자.
import {Component} from "react"; //반드시
class ClassCom extends Component{ //Componet란 클래스로부터 상속을 받겠다
render(){ //render하위에 있는 jsx코드를 반환하겠다
return(
<div>
클래스형 컴포넌트
</div>
)
}
}
export default ClassCom; //외부로 export
App.tsx에서 해당 컴포넌트를 불러올때 import 해준 뒤 return안에 태그형식으로 불러와주면된다.
import React from 'react';
import logo from './logo.svg';
import './App.css';
import ClassCom from './ClassCom';
function App() {
let name = "리액트";
return (
<div className = "container ">
<ClassCom></ClassCom>
</div>
);
}
export default App;
2) 함수형 컴포넌트
함수형 컴포넌트 실습을 위해 새로운 파일 FuncCom.tsx를 만들어보자.
import React from "react";
function FuncCom(){
return(
<div>
함수형 컴포넌트
</div>
)
}
// const FuncCom = () => 다음처럼 화살표 함수로 만들어도된다.
// {
// return(
// <div>
// 함수형 컴포넌트
// </div>
// )
// }
export default FuncCom;
App.tsx에서 해당 컴포넌트를 불러올때 import 해준 뒤 return안에 태그형식으로 불러와주면된다.
import React from 'react';
import logo from './logo.svg';
import './App.css';
import ClassCom from './ClassCom';
import FuncCom from './FuncCom';
function App() {
let name = "리액트";
return (
<div className = "container ">
<FuncCom></FuncCom>
</div>
);
}
export default App;
CHAPTER 2. state, hook, 구조분해할당, type
✅state
리액트에서 일반 변수 사용시 상태 관리가 되지 않는다. 이때 state사용하면 관리가 가능하다. state란 리액트 컴포넌트 내부에서 관리하는 데이터나 상태를 나타낸다. 리액트에서는 state가 변경될 때마다 컴포넌트가 다시 렌더링되어 UI가 최신 상태를 유지하도록 한다.
State 예시
import React, {useState} from 'react';
const TodoList : React.FC = () => {
const title : string = "오늘 할일";
const [todos, setTodos] = useState<string[]>(['공부하기','잠자기','미팅하기']);
return(
<div>
<h1>{title}</h1>
<p></p>
<div className='container'>
<ul>
<li>{todos[0]}</li>
<li>{todos[1]}</li>
<li>{todos[2]}</li>
</ul>
</div>
</div>
)
}
export default TodoList;
이 배열에서 두번째 자리의 원소는 state를 바꿔줄 수 있는 함수를 포함시킨 것이다.
✅Hook(훅)
리액트 훅(Hook)은 함수형 컴포넌트에서도 상태 관리와 라이프사이클 메서드 같은 기능을 사용할 수 있게 해 주는 API이다 . 이전에는 클래스형 컴포넌트에서만 상태와 라이프사이클을 사용할 수 있었지만, 훅이 등장하면서 함수형 컴포넌트에서도 동일한 기능을 활용할 수 있게 되었다.
위의 코드에서 useState는 상태를 정의하고, 그 상태를 업데이트하는 함수를 제공하는 훅이다.
✔️구조 분해 할당
const person = {
name: "jina",
age : 24,
city : 'seoul'
}
const {name, age, city} = person;
console.log(name);
console.log(age);
console.log(city);
✔️type
type Todo = {
id : number;
text : string;
isChecked : boolean;
}
const TodoList : React.FC = () => {
const title : string = "오늘 할일";
const [todos, setTodos] = useState<Todo[]>([
{ id : 1, text :'공부하기', isChecked : false},
{id : 2, text : '잠자기', isChecked : false},
{id : 3, text : '미팅하기', isChecked : false}
]);
return(
html코드작성
)
}
※ useState 기본 문법
const [state, setState] = useState<타입형식>(초기값)
useState의 상태 업데이트 함수의 형식
1. 새값을 직접 전달하는 방식: 기존 상태를 새로운 값으로 덮어쓴다.
setState(newValue);
2. 이전 상태를 기반으로 업데이트하는 방식 (함수형 업데이트) : 이전 상태를 기반으로 새로운 상태를 계산할 때 유용하다. setState에 함수를 전달하면 그 함수의 인자로 현재 상태 값(prevState)이 들어온다.
setState((prevState) => {
// 새로운 상태 계산
return newState;
});
※ 암시적 할당
타입스크립트 (및 자바스크립트)에서 화살표 함수를 사용할 때 중괄호 { }를 생략하면 return 키워드 없이도 값이 자동으로 반환된다. 이를 암시적 반환이라고 한다.
const add = (a: number, b: number) => a + b;
// 위 함수는 다음과 동일합니다.
const addExplicit = (a: number, b: number) => {
return a + b;
};
CHAPTER 3. map, filter
✔️map
jsx에서는 for문 대신에 map을 이용하여 반복하는 데이터를 처리할 수 있다. 이때 li에는 key값이 설정되도록 해주는데 이는 변경된 html만 랜더링, 최적화 되도록 해주기 위해서이다.
const MapTest = () => {
const fruits = ['apple', 'banana', 'orange'];
return (
<div>
<h2>
과일
</h2>
<ul>
{
fruits.map((fruit, index)=>((
<li key = {index}>{fruit}</li>
)))
}
</ul>
</div>
)
}
✔️filter
filter함수는 배열의 값 중에서 조건에 맞는 모든 값을 새로운 배열로 만들어 반환한다.
이때 모든 배열 안 값들을 검사하게 된다.
const removeTodo = (id : number) =>{
setTodos(todos.filter((todo)=> todo.id !== id))
}
CHAPTER 4. 얕은 복사 vs 깊은 복사
✅얕은 복사(Shallow Copy)
얕은 복사는 배열의 메모리 주소만 복사하여 원본가 같은 주소를 가르키게 된다. 따라서 얕은 복사를 할 경우, 중첩된 객체나 배열을 변경하면 원본 객체도 영향을 받는다.
ex) Object.assign(), Spread 연산자(...)
let original = { a: 1, b: { c: 2 } };
let shallowCopy = { ...original }; // Spread 연산자로 얕은 복사
shallowCopy.b.c = 3;
console.log(original.b.c); // 3, 원본 객체도 영향을 받음
✅깊은 복사(Deep Copy)
깊은 복사는 객체나 배열 내의 모든 데이터를 새로운 메모리 공간에 복사하는 방식이다. 즉, 복사본과 원본이 완전히 독립적인 데이터를 가지며, 복사된 객체를 수정해도 원본에 영향을 주지 않는다.
ex)
- JSON 방법: JSON.parse(JSON.stringify(obj)) (단, 함수나 undefined 같은 값은 복사되지 않습니다)
- Lodash 라이브러리의 _.cloneDeep() 메서드
- structuredClone() (브라우저의 최신 API)
let original = { a: 1, b: { c: 2 } };
let deepCopy = JSON.parse(JSON.stringify(original)); // 깊은 복사
deepCopy.b.c = 3;
console.log(original.b.c); // 2, 원본 객체는 영향을 받지 않음
주의할 점: JSON 방법은 단순한 객체/배열에서는 유용하지만, 함수, undefined, Symbol 등과 같이 JSON에 포함되지 않는 요소들은 복사되지 않는다.
'웹풀스택 일일정리' 카테고리의 다른 글
12주차-파트01: SPA, snippet단축키, 실습준비, redux개념, slice, Provider, Hooks (0) | 2024.11.04 |
---|---|
11주차:파트05: props, optional chaining (0) | 2024.11.01 |
11주차-파트03: 리액트 개념, jsx 문법 (0) | 2024.10.30 |
11주차-파트02: 리터럴, any타입, 유니온, 타입별칭, 타입가드, Array와 Tuple, Spread 연산자, 클래스와 객체(생성자, 접근지정자, getter 와 setter) (0) | 2024.10.29 |
11주차-파트01: 타입스크립트, 데이터타입, 인터페이스, 열거형 (0) | 2024.10.28 |