생활코딩 React 강의 (9) - update 구현
update를 위해 필요한 것
1. 기존 자료를 form에 불러오기
2. form안에서 수정하기
3. 수정된 자료를 저장하기
1. 기존 자료를 form에 불러오기
일단 UpdateComponent를 만든다. CreateComponent와 구성은 같고 기능이 다르다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
import React, { Component } from 'react';
class UpdateContent extends Component {
render() {
return (
<article>
<h2>Update</h2>
<form action="/create_process" method="post">
<p>
<input
type="text"
name="title"
placeholder="title"
></input></p>
<p>
<textarea
name="desc"
placeholder="description"
></textarea>
</p>
<p>
<input type="submit"></input>
</p>
</form>
</article>
);
}
}
export default UpdateContent
|
cs |
기본 구조는 위와 같다.
2. form 안에서 수정하기 - 제어 컴포넌트
props는 전달된 하위 컴포넌트에서는 변경할 수 없다. state를 이용해 입력값을 전달받아야 한다.
title과 desc를 입력받는 input과 textarea를 react로 제어하려면 value와 onChange 속성을 react가 원하는대로 설정해주어야 한다.
입력값을 state에서 관리할 수 있도록 state에 id, title, desc를 만들어준다.
1
2
3
4
5
6
7
8
9
10
|
class UpdateContent extends Component {
constructor(props) {
super(props);
this.state = {
id: this.props.data.id,
title: this.props.data.title,
desc: this.props.data.desc
}
}
}
|
cs |
title을 입력하는 input에서 value와 onChange를 설정해준다.
1
2
3
4
5
6
7
8
9
10
11
|
<p>
<input
type="text"
name="title"
placeholder="title"
value={this.state.title}
onChange={function(e){
this.setState({title:e.target.value})
}.bind(this)}
></input>
</p>
|
cs |
value는 state의 value를, onChange에서는 setState를 이용해 title을 input 안에 작성된 내용으로 바꿔준다.
onChange는 값이 바뀔 때 마다 실행되기 때문에 submit을 하기 전에도 실시간으로 state.title이 바뀐다.
onChange에 사용된 익명함수는 desc를 입력하는 textarea에도 사용해야 하므로 함수를 만들어 재사용하는 것이 좋다.
1
2
3
4
5
6
7
8
9
10
11
|
class UpdateContent extends Component {
inputFormHandler(e){
this.setState({[e.target.name]:e.target.value})
}
// ...
<input type="text" name="title" placeholder="title"
value={this.state.title}
onChange={this.inputFormHandler.bind(this)}
></input>
|
cs |
inputFormHandler()는 title과 desc 둘 다 바꿀 수 있는 함수여야 한다.
키에 대괄호를 사용하면 e.target.name에 따라 setState안에 {title: e.target.value}나 {desc: e.target.value} 로 따로 설정해주지 않아도 된다. 변수 키를 사용해야할 때 유용하다.
(참고: https://velog.io/@bigbrothershin/React-초기-설정-웹팩-설정-2020.2.5)
inputFormHandler()를 .bind(this)까지 state로 저장해주면 더 깔끔하게 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class UpdateContent extends Component {
constructor(){
// ...
this.inputFormHandler = this.inputFormHandler.bind(this);
}
inputFormHandler(e){
this.setState({[e.target.name]:e.target.value})
}
// ...
<input type="text" name="title" placeholder="title"
value={this.state.title}
onChange={this.inputFormHandler}
></input>
<textarea name="desc" placeholder="description"
value={this.state.desc}
onChange={this.inputFormHandler}
></textarea>
|
cs |
form에는 onSubmit을 통해 form이 제출되었을 때 상위 컴포넌트에 자료가 전달되도록 한다.
수정할 자료를 찾기 위해서는 id가 필요하므로 type="hidden"인 input을 만들어 form에서 입력받는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<form action="/create_process" method="post"
onSubmit={function(e){
e.preventDefault();
this.props.onSubmit(
this.state.id,
this.state.title,
this.state.desc
);
}.bind(this)}
>
// id를 입력하기 위한 보이지 않는 input
<input type="hidden" name="id" value={this.state.id}></input>
// ...
</form>
|
cs |
this.props.onSubmit의 입력값으로 event.target.title.value를 사용하지 않아도 onChange를 통해 state에 갱신되므로 this.state.title을 사용해도 된다.
UpdateComponent의 전체 코드는 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
import React, { Component } from 'react';
class UpdateContent extends Component {
constructor(props) {
super(props);
this.state = {
id: this.props.data.id,
title: this.props.data.title,
desc: this.props.data.desc
}
this.inputFormHandler = this.inputFormHandler.bind(this);
}
inputFormHandler(e){
this.setState({[e.target.name]:e.target.value})
}
render() {
console.log(this.props.data);
console.log("UpdateContent render");
return (
<article>
<h2>Update</h2>
<form action="/create_process" method="post"
onSubmit={function(e){
e.preventDefault();
this.props.onSubmit(
this.state.id,
this.state.title,
this.state.desc
);
}.bind(this)}
>
<input type="hidden" name="id" value={this.state.id}></input>
<p>
<input
type="text"
name="title"
placeholder="title"
value={this.state.title}
onChange={this.inputFormHandler}
></input></p>
<p>
<textarea
name="desc"
placeholder="description"
value={this.state.desc}
onChange={this.inputFormHandler}
></textarea>
</p>
<p>
<input type="submit"></input>
</p>
</form>
</article>
);
}
}
export default UpdateContent
|
cs |
3. 수정된 자료를 저장하기
상위 컴포넌트인 App에서 mode === "update"인 경우 나타낼 내용을 만들어준다.
UpdateComponent에서 onSubmit을 통해 전달받은 _id, _title, _desc를 처리할 수 있어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
else if (this.state.mode === "update") {
_content = this.getReadContent();
_article = <UpdateContent data={_content} onSubmit={function(_id, _title, _desc){
var _contents = Array.from(this.state.contents);
var i = 0;
while(i < _contents.length){
if(_contents[i].id === _id) {
_contents[i] = {id:_id, title:_title, desc:_desc}
break;
}
i = i + 1;
}
this.setState({
contents: _contents,
mode: "read"
})
}.bind(this)}></UpdateContent>
}
|
cs |
state의 contents에서 같은 id를 가지는 자료를 찾으면 입력받은 _title과 _desc로 변경해준다.
수정할 때도 contents를 바로 수정하지 않고 복사본을 만들어 수정한 후, setState를 통해 다시 지정해준다(immutable).
수정 후에는 수정된 내용을 read모드로 불러들이도록 mode를 바꾼다.
참고한 페이지
생활코딩 React 강의
20.1 update 구현
20.2 update 구현 : form
20.3 update 구현 : state 변경
https://ko.reactjs.org/docs/forms.html
https://velog.io/@bigbrothershin/React-초기-설정-웹팩-설정-2020.2.5