Iriton's log
누구든지 하는 리액트 7편: 배열 다루기 (1) 생성과 렌더링 본문
참고 자료
React에서는 state의 값을 직접 수정하면 안 된다.
불변성 유지 (데이터의 원본이 훼손되는 것을 막는 것) 때문인데 내장 함수(push, splice, unshift, pop) 배열 자체를 직접 수정하면 안 돼서 기존의 배열에 기반하여 새 배열을 만드는 함수(concat, slice, map, filter)를 사용해야 한다.
데이터 추가
import React, { Component } from "react";
import PhoneForm from "./components/PhoneForm";
class App extends Component {
id = 2;
state = {
information: [
{
id: 0,
name: "김민준",
phone: "010-0000-0000",
},
{
id: 1,
name: "홍길동",
phone: "010-0000-0001",
},
],
};
handleCreate = (data) => {
const { information } = this.state;
this.setState({
information: information.concat({ id: this.id++, ...data }),
});
};
render() {
const { information } = this.state;
return (
<div>
<PhoneForm onCreate={this.handleCreate} />
{JSON.stringify(information)}
</div>
);
}
}
export default App;
- state 정의
- information 이라는 state 객체를 정의한다.
- handleCreate 메서드
- 새로운 연락처 정보를 추가하는 메서드
- data는 PhoneForm 컴포넌트로부터 전달된 새 연락처 정보 객체이다.
- 현재 state를 가져온다.
- concat 메서드를 사용해 증가한 id와 …data 즉, 그 외 데이터까지 포함한다.
- 이로 인해 컴포넌트가 다시 렌더링 된다.
- 렌더링
- PhoneForm 컴포넌트를 렌더링 하고 onCreate prop로 handleCreate 메서드를 전달한다. 이로써 PhoneForm에서 새로운 연락처를 생성할 때 이 메서드가 호출되도록 한다.
- 현재 저장된 information을 JSON 형식의 문자열로 변환하여 화면에 표시한다.
- PhoneForm 컴포넌트와 연동
- onCreate 콜백을 통해 App 컴포넌트로 전달
- App 컴포넌트는 전달받은 데이터를 handleCreate 메서드를 통해 information 상태에 추가
이제 위 배열을 컴포넌트로 변환하자.
map 함수
const a = [1,2,3,4,5];
위와 같은 배열이 있다고 가정했을 때 내부 원소들에 2씩 곱하고 싶다면
const a = [1,2,3,4,5];
const b = [];
b.forEach(number => b.push(number * 2));
위와 같은 방식으로 코드를 짤 수도 있지만
const a = [1,2,3,4,5];
const b = a.map(number => number * 2);
map을 사용하면 더 쉽게 해결할 수 있다.
컴포넌트 만들기
두 개의 컴포넌트를 만들 것이다.
PhoneInfo : 각 전화번호 정보를 보여 주는 컴포넌트
PhoneInfoList : 여러 개의 PhoneInfo 컴포넌트들을 보여 줌.
// file: src/components/PhoneInfo.js
import React, { Component } from 'react';
class PhoneInfo extends Component {
static defaultProps = {
info: {
name: '이름',
phone: '010-0000-0000',
id: 0
}
}
render() {
const style = {
border: '1px solid black',
padding: '8px',
margin: '8px'
};
const {
name, phone, id
} = this.props.info;
return (
<div style={style}>
<div><b>{name}</b></div>
<div>{phone}</div>
</div>
);
}
}
export default PhoneInfo;
defaultProps은 info의 기본값을 설정함으로써 info 값 전달하는 것을 까먹게 된다 해도 crash 되는 것을 방지한다.
// src/components/PhoneInfoList.js
import React, { Component } from 'react';
import PhoneInfo from './PhoneInfo';
class PhoneInfoList extends Component {
static defaultProps = {
data: []
}
render() {
const { data } = this.props;
const list = data.map(
info => (<PhoneInfo key={info.id} info={info}/>)
);
return (
<div>
{list}
</div>
);
}
}
export default PhoneInfoList;
PhoneInfo 컴포넌트를 import 하여 data 라는 배열을 가져와서 map을 통해 JSX로 변환한다. 이 과정에서 key라는 값도 추가됐다. 이 key는 React에서 배열을 렌더링할 때 꼭 필요한 값이다.
현재는 id로 key를 사용하고 있는데, 데이터베이스에 데이터를 추가하게 된다면 고유 id를 사용하게 될 것이다.
key를 사용하는 이유는 데이터를 추가할 때마다 고정적인 고유 값을 부여해 줌으로써 React가 변화를 감지해내고 업데이트를 하게 될 때 조금 더 똑똑하게 처리할 수 있게 되기 때문이다.
// file: src/App.js
import React, { Component } from 'react';
import PhoneForm from './components/PhoneForm';
import PhoneInfoList from './components/PhoneInfoList';
class App extends Component {
id = 2
state = {
information: [
{
id: 0,
name: '김민준',
phone: '010-0000-0000'
},
{
id: 1,
name: '홍길동',
phone: '010-0000-0001'
}
]
}
handleCreate = (data) => {
const { information } = this.state;
this.setState({
information: information.concat({ id: this.id++, ...data })
})
}
render() {
return (
<div>
<PhoneForm
onCreate={this.handleCreate}
/>
<PhoneInfoList data={this.state.information}/>
</div>
);
}
}
export default App;
'Frontend > Study' 카테고리의 다른 글
누구든지 하는 리액트 8편: 배열 다루기 (2) 제거와 수정 (0) | 2024.10.16 |
---|---|
누구든지 하는 리액트 6편: input 상태 관리하기 (0) | 2024.10.16 |
누구든지 하는 리액트 5편: LifeCycle API (0) | 2024.10.16 |
누구든지 하는 리액트 4편: props 와 state (0) | 2024.10.16 |
누구든지 하는 리액트 3편: JSX (1) | 2024.10.16 |