해당 페이지 아래에서 퀴즈도 풀어보자 : )
[React] 기능 구현_①App에서 todos 상태 사용하기를 보면 를 원래는 3번 작성했던 걸 map으로 수정하게 되는 부분이 있다. 이 map함수에 대해 좀 더 알아보기로 했다.
📍 map 함수
- 자바스크립트 배열 객체의 내장 함수로 반복되는 컴포넌트를 렌더링하기 위해 사용한다.
- 파라미터로 전달된 함수를 사용해 배열 내 각 요소를 원하는 규칙에 따라 변환한 후, 새로운 배열을 생성한다.
📍 map 함수 사용 방법
기본적인 문법은 아래와 같다.array.map((element, index) => { // 새로운 배열을 반환하는 로직 });
- array : map( )을 호출하는 원본 배열
- element : 배열의 각 요소(현재 요소)
- index: 각 요소(현재 요소)의 인덱스
import React from 'react';
const Map_practice = () => {
return (
<ul>
<li>인수</li>
<li>한솔</li>
<li>겨레</li>
<li>정선</li>
<li>정재</li>
</ul>
);
};
export default Map_practice;
import React from 'react';
const Map_practice = () => {
const array = ['인수', '한솔', '겨레', '정선', '정재'];
const index = array.map((element) => {
return <li key={element}>{element}</li>; // key 설정
});
return <ul>{index}</ul>;
};
export default Map_practice;

5개의 li 요소가 담긴 코드를 map( ) 함수를 쓰니 간결해진 것을 확인할 수 있다.

그런데, 공부 중인 책에서는 props로 받아 온 todos 배열을 배열 내장 함수 map을 통해 TodoListItem으로 이루어진 배열로 변환해서 렌더링해주도록 하고 있다.
주석된 코드를 보면 < TodoListItem />를 3번 반복 작성해줬는데, todos 배열이 TodoList에 props로 전달됨에 따라 굳이 3번 작성할 필요가 없어진 것!!!
이렇게 props로 받아 온 todos 배열은 내장 함수 map을 사용해서 TodoListItem으로 이루어진 배열로 변환해서 렌더링해 볼 수 있다.
📍 내장 함수 map을 사용해 컴포넌트로 변환하기
- 내장 함수 map을 사용해 컴포넌트로 변환할 때는 key props를 전달해줘야 한다.
- 리액트에서는 요소를 렌더링할 때 key 속성은 필수다.
- 고유한 값을 key로 사용하면 리액트가 항목을 더 효율적으로 추적하고 리렌더링 성능이 향상된다.
- 리액트에서는 Props를 통해 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 수 있다.
이미 예제로 작성해봤지만, 나에겐 복잡한 감이 있어 따로 예제를 작성해보았다.
예제는 [React] map( ) 함수로 컴포넌트 만들기 (+ 컴포넌트 반복하기) 여기서 확인 가능!
[React] 기능 구현_②항목 추가 기능 구현 부분에서는 todos 배열에 새 객체 추가하는 onInsert 함수를 만들었다.
이때 useState가 아닌 useRef를 사용했는데, 왜 useRef를 사용했는지 충분한 이해가 되지 않아 더 확인해보기로 했다.
📍 useState
- React의 가장 기본적인 Hook으로 함수형 컴포넌트에서 가변적인 상태를 관리할 수 있도록 해 줌.
- 상태가 변경되면 해당 컴포넌트를 다시 렌더링함.
- 함수형 컴포넌트에서 상태를 관리해야 할 때 주로 사용함.
// useState 기본 구조 import React, { useState } from "react"; const ['현재 상태값', '상태를 업데이트하는 함수'] = useState('초기값');
import React, { useState } from "react"; // useState 임포트 필수!
function Counter() {
// count 상태 선언 [ 현재 상태값 , 상태를 업데이트하는 함수]
// 초기값은 0
const [count, setCount] = useState(0);
// 버튼 클릭 시 count + 1 증가
const CounterUP = () => {
setCount(count + 1); // 상태를 업데이트
};
return (
<div>
<h1>Clicked {count} times</h1>
<button onClick={CounterUP}>클릭해보세요</button>
</div>
);
}
export default Counter;
📍 useRef
- 함수형 컴포넌트 내에서 DOM 요소나 다른 React 요소를 참조하기 위해 사용되는 Hook
- 값이 변경되어도 컴포넌트를 다시 렌더링하지 않아 특정 값이나 DOM 요소를 효율적으로 관리할 수 있음.
- 함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해 줌.
- ref는 React에서 특정 DOM 요소나 React 컴포넌트에 직접 접근할 수 있도록 해주는 '참조(reference)'를 말 함.
[React] 기능 구현_③지우기 기능 구현 부분에서는 배열 내장 함수인 filter 함수를 사용했다.
📍 filter 함수
- filter 함수는 기존의 배열은 그대로 둔 상태에서 특정 조건을 만족하는 원소들만 따로 추출하여 새로운 배열을 만들어 준다.
- 리액트 컴포넌트에서 배열의 불변성을 지키면서 배열 원소를 제거해야 할 경우, 배열 내장 함수인 filter를 사용하면 매우 간편하게 가능하다.
- filter 함수에는 조건을 확인해 주는 함수를 파라미터로 넣어 줘야한다.
- 파라미터로 넣는 함수는 true 혹은 false 값을 반환해야 한다. 이때, true를 반환하는 경우만 새로운 배열에 포함된다.
- 즉, 조건을 만족하는 요소만 포함한 새로운 배열을 반환하며, 원본 배열은 변경되지 않는다.
📍 filter 함수 사용 방법
기본적인 문법은 아래와 같다.const newArray = array.filter((element, index, array) => { // 조건 작성 return condition; });
- element : 현재 처리 중인 배열의 요소
- index(선택적) : 현재 요소의 인덱스
- array(선택적): filter가 호출된 원본 배열
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const biggerThanFive = array.filter(number => number > 5);
// 결과: [6, 7, 8, 9, 10]
array.filter()는 배열 array의 각 요소를 순회하며, 조건 number > 5를 검사한다.
조건이 true인 요소만 새로운 배열에 추가하고, false인 요소는 제외된다.
최종적으로 [6, 7, 8, 9, 10]이 반환되는 것!
[React] 11장. 컴포넌트 성능 최적화 부분에서는 렉을 경험하기 위해 많은 데이터를 렌더링해 보는 예제를 작성해보았다.
2000여 개가 넘는 데이터가 생기면서 확실히 느려진 것을 느꼈다.
느려지는 원인은 11장 링크로 들어가서 확인해보자!
📍 React.memo
- 컴포넌트 리렌더링 방지 시 shouldComponentUpdate 라이프사이클을 사용하면 되는데, 함수형 컴포넌트에서는 라이프사이클 메서드 사용이 불가능해서 React.memo 함수를 사용한다.
- React.memo 함수는 React의 함수 컴포넌트 최적화를 돕는 함수로 컴포넌트가 동일한 props로 렌더링 될 때 리렌더링을 방지할 수 있다. 즉, 불필요한 렌더링을 줄여 성능 향상에 도움이 될 수 있다는 것!
📍 React.memo 함수 사용법
컴포넌트를 만들고 나서 감싸 주기만 하면 된다.
// 예시1
const TodoListItem = ({ todo, onRemove, onToggle }) => {
(...)
};
export default React.memo(TodoListItem);
// 예제 2
import React, { memo } from 'react';
const MyComponent = memo(({ text }) => <div>{text}</div>);
export default MyComponent;
📍 useState의 함수형 업데이트 기능
상태를 업데이트할 때, 이전 상태 값을 직접 참조하지 않고, 상태 업데이트 함수를 통해 최신 상태를 안전하게 가져와서 업데이트하는 방식이다.
// 할일 추가
const onInsert = useCallback(
(text) => {
const todo = {
id: nextId.current,
text,
checked: false,
};
// 1)useState의 함수형 업데이트 사용 전 기존 코드
// setTodos(todos.concat(todo));
// 2) useState의 함수형 업데이트 사용 코드
// 현재 상태(todos)를 setTodos 함수의 인자로 전달
// 전달된 상태(todos)는 함수 내부에서 "업데이트 전 상태"이기도 함.
// 전달된 상태(todos)를 함수의 매개변수로 넘김.
setTodos((todos) => todos.concat(todo)); //새로운 todo를 추가한 새로운 배열을 반환하고 새로운 상태를 업데이트함
nextId.current += 1; // 할 일 id값 +1 증가
},
[todos],
);