반복되는 코드의 경우 컴포넌트화 하기 위해 배열의 내장 함수인 map함수를 사용해서 랜더링 할 수 있다.
array.map(콜백함수, thisArg)
- 콜백 함수
-currentValue : 현재 요소
-index : currentValue의 인덱스 값
-array: 현재 처리하고 있는 원본 배열- thisArg : 콜백함수 내부에서 사용할 this
import React, { Component } from 'react'
class IterationSample extends Component {
render() {
return (
<ul>
<li>눈사람</li>
<li>얼음</li>
<li>뉸</li>
<li>바람</li>
<li>엘겨울</li>
</ul>
)
}
}
export default IterationSample
⬇클래스형 컴포넌트로 map()함수를 이용해서 반복되는 코드를 간결화
import React, { Component } from "react";
class IterationSample extends Component {
state = {
names: ["눈사람", "얼음", "눈", "바람"],
};
render() {
return (
<ul>
{this.state.names.map((name, index) => {
return <li key={index}>{name}</li>;
})}
</ul>
);
}
}
export default IterationSample;
리액트에서 key의 역할은 배열을 랜더링했을 떄, 리스트를 순차적으로 비교하면서 변화를 감지하는 속도를 높이는 것이다. 데이터의 고유값을 식별하는 역할이므로 언제가 유일해야 한다.
import React, { Component } from "react";
class IterationSample extends Component {
state = {
names: [
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" },
],
inputText: "",
newxId: 5,
};
render() {
return (
<ul>
{this.state.names.map((name) => {
return <li key={name.id}>{name.text}</li>;
})}
</ul>
);
}
}
export default IterationSample;
클래스형 컴포넌트 사용,
key값을 index 대신 name의 id값(name.id)로 설정
import React, { Component } from "react";
class IterationSample extends Component {
state = {
names: [
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" },
],
inputText: "",
nextId: 5,
};
handleChange = (e) => {
this.setState({
inputText: e.target.value,
});
};
handleAddTextButton = () => {
this.setState({
names: [...this.state.names].concat({
id: this.state.nextId,
text: this.state.inputText,
}),
inputText: "",
nextId: this.state.nextId + 1,
});
};
render() {
const { names } = this.state;
return (
<>
<input
type="text"
value={this.state.inputText}
onChange={this.handleChange}
/>
<button onClick={this.handleAddTextButton}>추가</button>
<ul>
{names.map((name) => (
<li key={name.id}>{name.text}</li>
))}
</ul>
</>
);
}
}
export default IterationSample;
배열 항목 추가시 push가 아닌 concat 사용 : push는 원본배열을 자체를 변경, concat은 새로운 배열을 만들어준다
➡ 원본 배열 자체를 수정하는 메서드를 사용할때에는 원본 값이 변경되므로 주의해서 사용하거나, 미리 원본을 다른 변수에 넣어 놓아야 한다.
(참고 : 원본 배열 자체를 변경하는 메서드 : push(), unshift(), shift(), pop()
➡ 리액트에서는 상태를 업데이트 할 때 기존 상태를 그대로 두면서 새로운 값을 설정해야 함!(불변성 유지 → 컴포넌트 최적화)
import React, { Component } from "react";
class IterationSample extends Component {
state = {
names: [
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" },
],
inputText: "",
nextId: 5,
};
handleChange = (e) => {
this.setState({
inputText: e.target.value,
});
};
handleAddTextButton = () => {
this.setState({
names: [...this.state.names].concat({
id: this.state.nextId,
text: this.state.inputText,
}),
inputText: "",
nextId: this.state.nextId + 1,
});
};
removeText = (id) => {
const { names } = this.state;
this.setState({
names: names.filter((name) => name.id !== id),
});
};
render() {
const { names } = this.state;
return (
<>
<input
type="text"
value={this.state.inputText}
onChange={this.handleChange}
/>
<button onClick={this.handleAddTextButton}>추가</button>
<ul>
{names.map((name) => (
<li key={name.id} onDoubleClick={() => this.removeText(name.id)}>
{name.text}
</li>
))}
</ul>
</>
);
}
}
export default IterationSample;
배열의 내장 함수 filter 사용 : 불변성 유지
필터링해서 특정 조건을 만족하는 데이터만 새로운 배열로 반환한다.
onRemove() 활용해서 내가 클릭한 li만 없애주기 구현