1. 자바스크립트 배열의 map() 함수
자바스크립트 배열 객체의 내장 함수인 map 함수를 사용하여 반복되는 컴포넌트를 렌더링 할 수 있다.
2. 문법
arr.map(callback, [thisArg])
함수의 파라미터
- callback : 새로운 배열의 요소를 생성하는 함수로 파라미터는 다음 세가지이다.
- currentValue : 현재 처리하고 있는 요소
- inext : 현재 처리하고 있는 요소의 index 값
- array : 현재 처리하고 있는 원본 배열
- thisArg(선택 항목) : callback 함수 내부에서 사용할 this 레퍼런스
3. 예제
let numbers = [1, 2, 3, 4];
let processd = numbers.map(function(num){
return num * num;
});
console.log(processed);
이처럼 map 함수를 사용해서 기존 배열로 새로운 배열를 만드는 역할 한다.
const numbers = [1, 2, 3, 4];
const result = numbers.map(num => num * num);
console.log(result);
4. 데이터 배열을 컴포넌트 배열로 변환하기
// 변경 전
return (
<div>
<ul>
<li>눈사람</li>
<li>얼음</li>
<li>눈</li>
<li>바람</li>
</ul>
</div>
);
// 변경 후
const IterationSample = () => {
const names = ["눈사람", "얼음", "눈", "바람"];
const nameList = names.map((name) => <li>{name}</li>);
return <ul>{nameList}</ul>;
};
map 함수에서 JSX를 작성할 때는 DOM 요소를 작성해도 되고, 컴포넌트를 사용해도 됨
5. App 컴포넌트에서 예제 컴포넌트 렌더링
렌더링이 되지만 콘솔을 보면 "key' prop이 없다는 경고 메세지를 표기
6. key
리액트에서는 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용함
key가 없을때는 VirtualDOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 감지
하지만 key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빠르게 알아 낼수 있음
7. key 설정
key를 설정할때는 함수 내부에서 컴포넌트 props를 설정하듯이 설정하면 됨
key 값은 언제나 유일해하기 때문에 데이터가 가진 고윳값을 key 값으로 설정해야함
예를들어 게시물을 렌더링 한다면 게시물 고유의 번호를 key 값으로 설정해야함
하지만 앞에 예제에는 고유 번호가 없음. 이런경우에는 콜백 함수의 인수인 index 값을 사용하면 됨
다만 고유한 값이 없을때만 index 값을 key로 사용해야함
index를 key로 사용하면 배열이 변경될 때 효율적으로 리렌더링하지 못함
const nameList = names.map((name, index) => <li key={index}>{name}</li>);
8. 응용
1. 초기 상태 설정하기
import { useState } from 'react';
const IterationSample = () => {
const [names, setName] = useState([
{id : 1, text: '눈사람' },
{id : 2, text: '얼음' },
{id : 3, text: '눈'},
{id : 4, text: '바람'}
]);
const [inputText, setInputText] = useState('');
const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 id
const nameList = names.map(name => <li key={name.id}>{name.text}</li>;
return <ul>{namesList}</ul>;
};
export default IterationSample;
2. 데이터 추가 기능 구현하기
const IterationSample = () => {
const [names, setNames] = useState([
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" },
]);
const [inputText, setInputText] = useState("");
const [nextId, setNextId] = useState(5);
const onChange = (e) => setInputText(e.target.value);
const onClick = () => {
const nextNames = names.concat({
id: nextId,
text: inputText,
});
setNextId(nextId + 1);
setNames(nextNames);
setInputText("");
};
const nameList = names.map((name, index) => (
<li key={name.id}>{name.text}</li>
));
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
9. 데이터 제거 기능
import { useState } from 'react';
const InterationSample = () => {
const [ name, setName ] = useState([
{ id : 1, text: '눈사람' },
{ id : 2, text: '얼름' },
{ id : 3, text: '눈' },
{ id : 4, text: '바람' }
]);
const [ Input, setInputText ] = useState('');
const [ nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 id
const onChange = e => setInputText(e.target.value);
const onClick = () => {
const nextNames = names.concat({
id : nextId, // nextId 값을 id로 설정하고
text : inputText
});
setNextId(nextId + 1); // nextId 값에 1을 더해 준다.
setNames(nextNames); // names 값을 업데이트 하다.
setInputText(''); // inputText를 비운다.
};
const nameList = names.map(name => <li key={name.id}>{name.text}<li>);
return (
<>
<input value = {inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
const onRemove = (id) => {
const nextNames = names.filter((name) => name.id !== id);
setNames(nextNames);
};
const nameList = names.map((name, index) => (
<li key={name.id} onDoubleClick={() => onRemove(name.id)}>
{name.text}
</li>
push 함수는 기존 배열 자체를 변경해주는 반면, concat은 새로운 배열을 만들어 준다는 차이점이 있음
리액트에서 상태를 업데이트할 때는 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야 함
이것을 불변성 유지라고 하는데 불변성 유지를 해주어야 나중에 리액트 컴포넌트의 성능을 최적화 할 수 있음
10. 정리
반복되는 렌더링하는 방법과 유동적인 배열에 대해 배움
컴포넌트 배열을 렌더링할 때는 key 값 설정에 항상 주의해야함
또 key 값은 언제나 유일해야지 렌더링 과정의 오류가 발생하지 않음
상태 안에서 배열을 변형할때는 직접 수정하는 것이 아닌 concat, filter 등의 배열 내장 함수를 사용하여 새로운 배열을 만든 후 이를 새로운 상태로 설정해 주어야 함
'React > 다시 공부하는 리액트' 카테고리의 다른 글
다시 공부하는 리액트 8장 Hooks (3) | 2023.07.06 |
---|---|
다시 공부하는 리액트 7장 컴포넌트의 라이프사이클 메서드 (1) | 2023.07.05 |
다시 공부하는 리액트 5장 ref.DOM 이름 달기 (0) | 2023.07.04 |
다시 공부하는 리액트 4장 이벤트 핸들링 (0) | 2023.07.03 |
다시 공부하는 리액트 3장 component, state (0) | 2023.07.02 |