반응형
배열을 다루는 CRUD 구현
생성과 렌더링
- 리액트애서는 state 내부의 값을 직접적으로 수정하면 절대로 안된다.
- 이를 불변성 유지라고 하는데, push, splice, unshift, pop 같은 내장함수는 배열 자체를 직접 수정하게 되므로 적합하지 않는다.
- 그 대신에, 기존의 배열에 기반하여 새 배열을 만들어내는 함수인 concat, slice, map, filter 같은 함수를 사용하면된다.
App.js
import React, { Component } from 'react';
import PhoneForm from "./components/PhoneForm";
import './App.css';
class App extends Component {
id =2
state = {
information:[
{
id: 0,
name: '김진석',
phone: '010-0000-0000'
},
{
id: 1,
name: '김진석2',
phone: '010-0000-0000'
}
]
}
handleCreate = (data)=>{
const {information} = this.state;
this.setState({
information: information.concat({ id: this.id++, ...data }) //concat을 이용하여 배열을 조절
}) //여기서 id 값은 각 데이터를 식별하기 위함이다.
}
render() {
const { information } = this.state;
return (
<div>
<PhoneForm
onCreate={this.handleCreate}
/>
<PhoneInfoList data={this.state.information}/>
</div>
);
}
}
export default App;
PhoneForm.js
import React, { Component } from 'react';
class PhoneForm extends Component {
state = {
name: '',
phone: ''
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault();
this.props.onCreate(this.state);
//submit이 끝나면 다시 폼 값을 초기화 시킨다.
this.setState({
name: '',
phone: ''
})
}
render() {
return (
<form onSubmit={this.handleSubmit}> //submit 버튼 누르면 반응하여 부모인 App.js로 폼 값 전달
<input
placeholder="이름"
value={this.state.name}
onChange={this.handleChange} //폼 값 수정시 반응
name="name"
/>
<input
placeholder="전화번호"
value={this.state.phone}
onChange={this.handleChange} //폼 값 수정시 반응
name="phone"
/>
<button type="submit">등록</button> //submiit 버튼 추가
</form>
);
}
}
export default PhoneForm;
데이터 랜더링
PhoneInfo.js
각 전화번호 정보를 보여주는 컴포넌트다.
import React, { Component } from 'react';
class PhoneInfo extends Component {
// info 가 undefined 일 때에는 비구조화 할당을 통해 내부의 값을 받아올 수 없기 때문에
//defaultProps 를 통하여 info 의 기본값을 설정해주었다.
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; //부모인 PhoneInfoList에서 props을 이용해 name, phone, id 값 가져옴
return (
<div style={style}>
<div><b>{name}</b></div>
<div>{phone}</div>
</div>
);
}
}
export default PhoneInfo;
PhoneInfoList.js
여러개의 PhoneInfo 컴포넌트들을 보여준다.
import React, { Component } from 'react';
import PhoneInfo from './PhoneInfo';
class PhoneInfoList extends Component {
static defaultProps = {
data: []
}
render() {
const { data } = this.props; //부모인 App.js에서 props을 이용해 data 값 가져옴
const list = data.map( //map 메소드를 이용하여 조건대로 배열 list을 새롭게 배열화시킨다.
info => (<PhoneInfo key={info.id} info={info}/>) //자식인 PhoneInfo로 props기능으로 전달
);
return (
<div>
{list}
</div>
);
}
}
export default PhoneInfoList;
- data 라는 배열을 가져와서 map 을 통하여 JSX 로 변환을 해준다.
- 이 과정에서, key 라는 값도 설정이 되었는데, 여기서 key 는 리액트에서 배열을 렌더링을 할 때 꼭 필요한 값이다.
데이터 제거
App.js
import React, { Component } from 'react';
import PhoneForm from "./components/PhoneForm";
import './App.css';
import PhoneInfoList from "./components/PhoneInfoList";
class App extends Component {
id =2
state = {
information:[
{
id: 0,
name: '김진석',
phone: '010-0000-0000'
},
{
id: 1,
name: '김진석2',
phone: '010-0000-0000'
}
]
}
handleCreate = (data)=>{
const {information} = this.state;
this.setState({
information: information.concat({ id: this.id++, ...data })
})
}
handleRemove = (id) => {
const { information } = this.state;
this.setState({
information: information.filter(info => info.id !== id)
})
}
render() {
const { information } = this.state;
return (
<div>
<PhoneForm
onCreate={this.handleCreate}
/>
//id 를 파라미터로 받아오는 handleRemove 라는 함수를 만들어,porps로 PhoneInfoList 로 전달
<PhoneInfoList data={this.state.information}
onRemove={this.handleRemove}
/>
</div>
);
}
}
export default App;
PhoneInfoList.js
import React, { Component } from 'react';
import PhoneInfo from './PhoneInfo';
class PhoneInfoList extends Component {
static defaultProps = {
data: []
}
//PhoneInfoList 에서는 props 로 전달받은 onRemove 를 그대로 다시 자식인 PhoneInfo로 전달한다.
render() {
const { data, onRemove } = this.props;
const list = data.map(
info => (<PhoneInfo key={info.id} info={info} onRemove={onRemove}/>)
);
return (
<div>
{list}
</div>
);
}
}
export default PhoneInfoList;
PhoneInfo.js
import React, { Component } from 'react';
class PhoneInfo extends Component {
static defaultProps = {
info: {
name: '이름',
phone: '010-0000-0000',
id: 0
}
}
handleRemove = () => {
// 삭제 버튼이 클릭되면 onRemove 에 id 넣어서 호출
const { info, onRemove } = this.props;
onRemove(info.id);
}
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>
<button onClick={this.handleRemove}>삭제</button>
</div>
);
}
}
export default PhoneInfo;
데이터 수정
App.js
import React, { Component } from 'react';
import PhoneForm from "./components/PhoneForm";
import './App.css';
import PhoneInfoList from "./components/PhoneInfoList";
class App extends Component {
id =2
state = {
information:[
{
id: 0,
name: '김진석',
phone: '010-0000-0000'
},
{
id: 1,
name: '김진석2',
phone: '010-0000-0000'
}
]
}
handleCreate = (data)=>{
const {information} = this.state;
this.setState({
information: information.concat({ id: this.id++, ...data })
})
}
handleRemove = (id) => {
const { information } = this.state;
this.setState({
information: information.filter(info => info.id !== id)
})
}
handleUpdate = (id, data) =>{
const {information} = this.state;
this.setState({
information: information.map(info => id === info.id ? { ...info, ...data }
// 새 객체를 만들어서 기존의 값과 전달받은 data 을 덮어씀
: info // 기존의 값을 그대로 유지
)
})
}
render() {
const { information } = this.state;
return (
<div>
<PhoneForm
onCreate={this.handleCreate}
/>
<PhoneInfoList data={this.state.information}
onRemove={this.handleRemove}
onUpdate={this.handleUpdate}
/>
</div>
);
}
}
export default App;
PhoneInfoList.js
import React, { Component } from 'react';
import PhoneInfo from './PhoneInfo';
class PhoneInfoList extends Component {
static defaultProps = {
data: []
}
render() {
const { data, onRemove, onUpdate } = this.props; //porps으로 부모에게 받아 onUpdate추가
const list = data.map(
info => (<PhoneInfo
key={info.id}
info={info}
onRemove={onRemove}
onUpdate={onUpdate}/>) //porps으로 다시 하위 자식으로 전달
);
return (
<div>
{list}
</div>
);
}
}
export default PhoneInfoList;
PhoneInfo.js
import React, { Component } from 'react';
class PhoneInfo extends Component {
static defaultProps = {
info: {
name: '이름',
phone: '010-0000-0000',
id: 0
}
}
state = {
editing: false,
name: '',
phone: '',
}
handleRemove = () => {
// 삭제 버튼이 클릭되면 onRemove 에 id 넣어서 호출
const { info, onRemove } = this.props;
onRemove(info.id);
}
// editing 값을 반전시키는 함수
// true -> false, false -> true
handleToggleEdit= ()=>{
const{editing} =this.state;
this.setState({
editing: !editing
});
}
// input 에서 onChange 이벤트가 발생 될 때
// 호출되는 함수
handleChange=(e)=>{
const{name, value}= e.target;
this.setState({
[name]: value
});
}
componentDidUpdate(prevProps, prevState){
// 여기서는 editing 값이 바뀔 때 처리 할 로직이 존재한다.
// 수정을 눌렀을땐, 기존의 값이 input에 나타나고,
// 수정을 적용할땐, input 의 값들을 부모한테 전달해준다.
const { info, onUpdate } = this.props;
if(!prevState.editing && this.state.editing) {
// editing 값이 false -> true 로 전환 될 때
// info 의 값을 state 에 넣어준다
this.setState({
name: info.name,
phone: info.phone
})
}
if (prevState.editing && !this.state.editing) {
// editing 값이 true -> false 로 전환 될 때
onUpdate(info.id, {
name: this.state.name,
phone: this.state.phone
});
}
}
render() {
const style = {
border: '1px solid black',
padding: '8px',
margin: '8px'
};
const {editing} = this.state;
if(editing){ //수정모드
return (
<div style={style}>
<div>
<input
value={this.state.name}
name="name"
placeholder="이름"
onChange={this.handleChange}
/>
</div>
<div>
<input
value={this.state.phone}
name="phone"
placeholder="전화번호"
onChange={this.handleChange}
/>
</div>
<button onClick={this.handleToggleEdit}>적용</button>
<button onClick={this.handleRemove}>삭제</button>
</div>
);
}
//일반모드
const {
name, phone
} = this.props.info;
return (
<div style={style}>
<div><b>{name}</b></div>
<div>{phone}</div>
<button onClick={this.handleToggleEdit}>수정</button>
<button onClick={this.handleRemove}>삭제</button>
</div>
);
}
}
export default PhoneInfo;
반응형
'프로그래밍 개발 > ReactJs' 카테고리의 다른 글
ReactJs - input (0) | 2021.01.06 |
---|---|
ReactJs - LifeCycle API (0) | 2021.01.06 |
ReactJs - props 와 state (0) | 2021.01.05 |
ReactJs - JSX 기본 (0) | 2021.01.05 |
ReactJs - Update , Delete기능 구현하기 (0) | 2021.01.04 |
댓글