update 구현 [2] - form

SPANKEEE·2023년 3월 17일
0

리액트-시작

목록 보기
28/30

from

이제 컴포넌트로 주입된 데이터를 기반으로 컴퍼넌트에 기본적으로 입력되는 값을 세팅해보자.

UpdateContent.js 파일로 들어온 데이터는 _content 변수를 통해 들어 있는 상태다.

  • UpdateArti.js > render > <form>영역
/* *기존
<p>
  <input type="text" name="title" placeholder="title"></input>
</p>
<p>
  <textarea name="desc" placeholder="description"></textarea>
</p>
<p>
  <input type="submit"></input>
</p> */
/** 수정 */
<p>
  <input 
	type = "text"
	name = "title"
	placeholder = "title"
	value={this.props.title}
  ></input>
</p>

위 코드를 추가한 뒤 업데이트 버튼을 클릭할 때 정상 작동하지 않고 경고 문구가 나오는 것을 확인할 수 있다.


Handler

그 내용은 props 를 직접 value 에 넣을 때 onChange 라고 불리는 핸들러를 사용하지 않으면 read-only 가 된다고 적혀있다.

value 값으로 컴포넌트 안에서 가변적인 데이터를 state화를 시켜줘야 한다.

아래와 같이 코드를 추가하자.

  • UpdateArti.js
import React, { Component } from 'react';
class UpdateArti extends Component {
  // constructor 함수 생성
  constructor(props){
    super(props);
    this.state = {
      titls:this.props.data.title
    }
  }
  // <input> 태그 수정
  <input type = "text"
		 name = "title"
		 placeholder = "title"
		 value = {this.state.title}
</input>

input valuestate가 내용을 수정하더라도 state 상태가 바뀌어야 되는 근거는 없기 때문에 여전히 수정되지 않는다.

input 값을 바꿨을 때 state 값을 바뀌게 해야 read-only 상태가 아니게 된다.

그래서 onChange 를 꼭 작성해야 한다.

  • UpdateArti.js > render > <form>영역
<p>
  <input type = "text" name = "title" placeholder = "title"
	value={this.props.title}
    onChange={function(e){
      console.log(e.target.value);
    }.bind(this)}
  ></input>
</p>

이벤트가 발생할 때 마다 어떤 값이 들어오는지 콘솔을 통해 확인해보자.

  • console 창

e.target.value 는 이벤트의 타겟인 input 태그의 value 값을 의미한다.

업데이트할 때마다 한글자씩 바뀌는 value 값들을 컴포넌트의 state 값에 바로 동기화를 시켜주도록 작성한다.

  • UpdateArti.js > render > <form>영역
<p>
  <input type = "text" name = "title" placeholder = "title"
	value={this.props.title}
    onChange={function(e){
      this.setState({title : e.target.value });
    }.bind(this)}
  ></input>
</p>

이제 업데이트 할 때 리액트 컴포넌트의 state 를 보면 내용을 바꾸는 것에 따라서 state 가 동적으로 바뀌는 것을 볼 수 있습니다.

<textarea> 태그도 처리해보자.

// constructor 함수
  constructor(props){
    super(props);
    this.state = {
      title : this.props.data.title,
      desc : this.props.data.desc
    }
  }
- - - 
// <textarea> 태그 수정
  	<textarea
	  onChange={function(e){
        this.setState({title : e.target.value });
      }.bind(this)}
      name = "desc"
	  placeholder = "description"
	  value = {this.state.desc}></textarea>

위 코드는 html처럼 보이지만 html이 아닌 리액트의 HTML이다.

리액트는 value를 추가해야 한다.

해당 코드를 실행하면 잘 동작하는 것을 확인할 수 있지만... 이런 식으로 하나하나 onChange 를 만들기 번거롭다.

그래서 inputFormHandler 라는 이름의 함수를 만들어서 중복을 제거해 준다.

// inputFormHander 함수 추가
  inputFormHandler(e){
    this.setState({title : e.target.value});
  }
// onChange 이벤트 내용 변화
  onChange = {this.inputFormHandler.bind(this)}

업데이트를 했을 때 이전과 똑같지만 반복되는 코드를 밖으로 빼내면서 가독성이 더욱 좋아졌다.

하지만 inputFormHander 함수는 title이라고 정해져 있기 때문에 <textarea> 태그의 onChange 이벤트에서는 동일하게 사용할 수 없는 문제가 남아있다.

이것을 해결하기 위해서 고정된 title 을 이벤트가 발생하고 있는 태그의 이름의 무엇인지 알아내는 코드로 변경해주자.

inputFormHander(e){
  this.setState({[e.target.name]:e.target.value});

<input>태그와 <textarea> 태그 모두 잘 동작하는 걸 확인할 수 있다.

하지만 bind(this) 를 계속 추가해줘야 하는 불편함이 남아있다.

constructor(props){
  this.inputFormHandler = this.inputFormHandler.bind(this);
  // ...
}

위 코드를 추가하여 깔끔하게 코드를 만드는 리팩토링을 한 것이다.

profile
해야되요

0개의 댓글