GitHub - gilbutITbook/080203: 리액트를 다루는 기술 개정판
리액트를 다루는 기술 개정판. Contribute to gilbutITbook/080203 development by creating an account on GitHub.
github.com
(본 포스팅은 위의 리액트를 다루는 기술(개정판)을 기반으로 작성했습니다.)
'자바스크립트 배열의 map() 함수'
- map 함수 : 반복되는 컴포넌트를 렌더링
- 피라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환 -> 새로운 배열 생성
문법 - 피라미터
arr.map(callback, [thisArg])
callback : 새로운 배열의 요소를 생성하는 함수, 파라미터는 세가지
- currentValue : 현재 처리하고 있는 요소
- index(선택 항목) : 현재 처리하고 있는 요소의 index 값
- array(선택 항목) : 현재 처리하고 있는 원본 배열
thisArg(선택 항목) : callback 함수 내부에서 사용할 this 레퍼런스
예제
var numbers = [1, 4, 9];
var doubles = numbers.map(function (num) {
return num * 2;
});
// doubles = [2, 8, 18]
var roots = numbers.map(Math.sqrt);
// roots = [1, 2, 3]
- call(), apply() 메소드 : 유사 배열 객체에 배열 메소드를 빌려 사용
- Math.sqrt 함수 : x의 제곱근을 반환하는 함수
let map = Array.prototype.map;
let a = map.call('Hello World', function (x) {
return x.charCodeAt(0);
});
var elems = document.querySelectorAll('select option:checked');
var values = [].map.call(elems, function (obj) {
return obj.value;
});
- Array.from() 사용
- x.charCodeAt() 함수 : 각 문자의 ASCII 인코딩 값을 가져오는 함수
- Array.prototype.map : 배열의 값, 인덱스, 배열 세 가지의 인자를 전달 -> 배열의 인덱스가 진법(radix)으로 전달되어 혼란스럽게 작동
'데이터 배열을 컴포넌트 배열로 변환하기'
IterationSample.js
import React from 'react';
const IterationSample = () => {
const names = ['눈사람', '얼음', '눈', '바람'];
const nameList = names.map((name) => <li>{name}</li>);
return <ul>{nameList}</ul>;
};
export default IterationSample;
App.js
import React, {Component} from 'react';
import IterationSample from './IterationSample';
class App extends Component {
render() {
return <IterationSample />;
}
}
export default App;
'Key'
위의 결과 값에 F12키를 눌러 콘솔 창을 확인한 경고 메세지

Key란 무엇일까?
- key는 컴포넌트 배열을 렌더링 했을 때, 어떤 원소에 변동이 있었는지 알아내기위해 사용
- 유동적인 데이터를 다룰 때는 원소를 새로 생성, 제거, 수정할 수 있음
- key가 없을 때 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화 감지
- key가 있으면 값을 이용해서 어떤 변화가 일어났느지 빠르게 알아낼 수 있음
Key 설정
- map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 함
- 데이터가 가진 고유값을 key 값으로 설정해야 함
- 고유 번호가 없을 경우, map 함수에 전달되는 콜백 함수의 인수인 index 값을 사용
const articleList = articles.map(article => (
<Article
title={article.title}
writer={article.writer}
key={article.id}
/>
);
'응용'
초기 상태 설정
import React, {useState} from 'react';
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 nameList = names.map((name) => <li key={name.id}>{name.text}</li>);
return <ul>{nameList}</ul>;
};
export default IterationSample;
IterationSample 컴포넌트에서 useState를 사용하여 상태를 설정한다. 또한 names에 text와 고유의 id를 담고있는객체들의 배열을 넣으며, 추가할 데이터를 입력받기 위해 inputText를 추가한다.
또한, nextId를 통해 추가될 데이터의 아이디를 계산한다.
추가 기능 구현
import React, {useState} from 'react';
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) => <li key={name.id}>{name.text}</li>);
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
export default IterationSample;
- onChange 함수를 통해 inputText를 입력받도록 함
- onClick 함수에서는 배열의 내장 함수 concat을 사용하여 새로운 항목을추가한 배열을 만들어줌
- 새로 만들어진 nextNames를 setNames로 상태를 업데이트
- concat 을 사용하는 이유 = push 함수는 기존 배열에 항목을 추가하는 것으로 기존 배열 자체를 변경하는 반면, concat 함수는 기존 배열에 항목을 추가한 새로운 배열을 만들어줌
불변성 유지 : 리액트에서 상태를 업데이트 할 때 -> 상태를 유지하며 새로운 값을 상태로 설정
제거 기능 구현 - filter 사용법
Array.prototype.filter()
import React, {useState} from 'react';
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 onRemove = (id) => {
const nextNames = names.filter((name) => name.id !== id);
setNames(nextNames);
};
const nameList = names.map((name) => (
<li key={name.id} onDoubleClick={() => onRemove(name.id)}>
{name.text}
</li>
));
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
export default IterationSample;
- onDoubleClick : HTML 요소를 더블클릭할 때 사용하는 이벤트
- onRemove 함수를 구현해서 각 li 요소에 이벤트로 등록
- onRemove 함수에서는 클릭할 때 클릭이 발생한 li 요소의 id를 매개변수로 받아 해당 id를 가진 name 객체를 제거
- 적용된 배열 nextNames 로 names를 업데이트
후기 및 정리
- 컴포넌트 배열을 렌더링할 때는 key 값 설정에 항상 주의한다.
- key 값은 유일해야한다.
- 상태 안에서 배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아닌 concat, filter 배열 내장 함수를 사용하여 새로운 배열을 만들고, 이를 새로운 상태로 설정해야 한다.
'React' 카테고리의 다른 글
8# Hooks (0) | 2023.02.09 |
---|---|
7# 컴포넌트의 라이프사이클 메서드 (0) | 2023.02.03 |
5# ref: DOM에 이름 달기 (0) | 2023.01.13 |
4# 이벤트 핸들링 (0) | 2023.01.05 |
3# 컴포넌트 (0) | 2022.12.30 |
GitHub - gilbutITbook/080203: 리액트를 다루는 기술 개정판
리액트를 다루는 기술 개정판. Contribute to gilbutITbook/080203 development by creating an account on GitHub.
github.com
(본 포스팅은 위의 리액트를 다루는 기술(개정판)을 기반으로 작성했습니다.)
'자바스크립트 배열의 map() 함수'
- map 함수 : 반복되는 컴포넌트를 렌더링
- 피라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환 -> 새로운 배열 생성
문법 - 피라미터
arr.map(callback, [thisArg])
callback : 새로운 배열의 요소를 생성하는 함수, 파라미터는 세가지
- currentValue : 현재 처리하고 있는 요소
- index(선택 항목) : 현재 처리하고 있는 요소의 index 값
- array(선택 항목) : 현재 처리하고 있는 원본 배열
thisArg(선택 항목) : callback 함수 내부에서 사용할 this 레퍼런스
예제
var numbers = [1, 4, 9];
var doubles = numbers.map(function (num) {
return num * 2;
});
// doubles = [2, 8, 18]
var roots = numbers.map(Math.sqrt);
// roots = [1, 2, 3]
- call(), apply() 메소드 : 유사 배열 객체에 배열 메소드를 빌려 사용
- Math.sqrt 함수 : x의 제곱근을 반환하는 함수
let map = Array.prototype.map;
let a = map.call('Hello World', function (x) {
return x.charCodeAt(0);
});
var elems = document.querySelectorAll('select option:checked');
var values = [].map.call(elems, function (obj) {
return obj.value;
});
- Array.from() 사용
- x.charCodeAt() 함수 : 각 문자의 ASCII 인코딩 값을 가져오는 함수
- Array.prototype.map : 배열의 값, 인덱스, 배열 세 가지의 인자를 전달 -> 배열의 인덱스가 진법(radix)으로 전달되어 혼란스럽게 작동
'데이터 배열을 컴포넌트 배열로 변환하기'
IterationSample.js
import React from 'react';
const IterationSample = () => {
const names = ['눈사람', '얼음', '눈', '바람'];
const nameList = names.map((name) => <li>{name}</li>);
return <ul>{nameList}</ul>;
};
export default IterationSample;
App.js
import React, {Component} from 'react';
import IterationSample from './IterationSample';
class App extends Component {
render() {
return <IterationSample />;
}
}
export default App;
'Key'
위의 결과 값에 F12키를 눌러 콘솔 창을 확인한 경고 메세지

Key란 무엇일까?
- key는 컴포넌트 배열을 렌더링 했을 때, 어떤 원소에 변동이 있었는지 알아내기위해 사용
- 유동적인 데이터를 다룰 때는 원소를 새로 생성, 제거, 수정할 수 있음
- key가 없을 때 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화 감지
- key가 있으면 값을 이용해서 어떤 변화가 일어났느지 빠르게 알아낼 수 있음
Key 설정
- map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 함
- 데이터가 가진 고유값을 key 값으로 설정해야 함
- 고유 번호가 없을 경우, map 함수에 전달되는 콜백 함수의 인수인 index 값을 사용
const articleList = articles.map(article => (
<Article
title={article.title}
writer={article.writer}
key={article.id}
/>
);
'응용'
초기 상태 설정
import React, {useState} from 'react';
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 nameList = names.map((name) => <li key={name.id}>{name.text}</li>);
return <ul>{nameList}</ul>;
};
export default IterationSample;
IterationSample 컴포넌트에서 useState를 사용하여 상태를 설정한다. 또한 names에 text와 고유의 id를 담고있는객체들의 배열을 넣으며, 추가할 데이터를 입력받기 위해 inputText를 추가한다.
또한, nextId를 통해 추가될 데이터의 아이디를 계산한다.
추가 기능 구현
import React, {useState} from 'react';
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) => <li key={name.id}>{name.text}</li>);
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
export default IterationSample;
- onChange 함수를 통해 inputText를 입력받도록 함
- onClick 함수에서는 배열의 내장 함수 concat을 사용하여 새로운 항목을추가한 배열을 만들어줌
- 새로 만들어진 nextNames를 setNames로 상태를 업데이트
- concat 을 사용하는 이유 = push 함수는 기존 배열에 항목을 추가하는 것으로 기존 배열 자체를 변경하는 반면, concat 함수는 기존 배열에 항목을 추가한 새로운 배열을 만들어줌
불변성 유지 : 리액트에서 상태를 업데이트 할 때 -> 상태를 유지하며 새로운 값을 상태로 설정
제거 기능 구현 - filter 사용법
Array.prototype.filter()
import React, {useState} from 'react';
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 onRemove = (id) => {
const nextNames = names.filter((name) => name.id !== id);
setNames(nextNames);
};
const nameList = names.map((name) => (
<li key={name.id} onDoubleClick={() => onRemove(name.id)}>
{name.text}
</li>
));
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
export default IterationSample;
- onDoubleClick : HTML 요소를 더블클릭할 때 사용하는 이벤트
- onRemove 함수를 구현해서 각 li 요소에 이벤트로 등록
- onRemove 함수에서는 클릭할 때 클릭이 발생한 li 요소의 id를 매개변수로 받아 해당 id를 가진 name 객체를 제거
- 적용된 배열 nextNames 로 names를 업데이트
후기 및 정리
- 컴포넌트 배열을 렌더링할 때는 key 값 설정에 항상 주의한다.
- key 값은 유일해야한다.
- 상태 안에서 배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아닌 concat, filter 배열 내장 함수를 사용하여 새로운 배열을 만들고, 이를 새로운 상태로 설정해야 한다.
'React' 카테고리의 다른 글
8# Hooks (0) | 2023.02.09 |
---|---|
7# 컴포넌트의 라이프사이클 메서드 (0) | 2023.02.03 |
5# ref: DOM에 이름 달기 (0) | 2023.01.13 |
4# 이벤트 핸들링 (0) | 2023.01.05 |
3# 컴포넌트 (0) | 2022.12.30 |