티스토리 뷰

React.JS

[React.JS] Forms

버미노트 2017. 4. 22. 00:40

React의 elements는 HTML의 elements와 달리 state로 값이 유지됩니다.

<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

위의 HTML 코드의 Submit 버튼을 누르면, 파라미터(?name=...)가 붙은 채 새로운 페이지를 로드되는 것을 확인 할 수 있습니다.

대부분의 경우에, Submit 버튼을 누르면 handler 함수가 실행되어, 입력받은 값을 처리하는 것이 더 유용할 경우가 많습니다. React에서 input, select, textarea 태그에서 입력 받은 값을 컨드롤 하는 방식을 "controlled components"라고 합니다.

1. Controlled components

React는 사용자의 입력 값에 따라 state의 값을 setState()로 업데이터하여, input, select, textarea 태그를 컨트롤 합니다.

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen으로 예제 확인하기

  • 4번 줄, 생성자에서 state를 초기화 해줍니다.
  • 6~7번 줄, 이밴드 핸들러에 this를 바인딩 해 줍니다. (this를 바인딩 해주지 않으면, React의 setState 등의 메소드를 사용하지 못합니다. [React.JS] Handling Events 참고)
  • 10~12번 줄, input에서 사용자가 값을 입력할 경우 호출되는 핸들러입니다.
  • 14~17번 줄, Submit 버튼을 누를 경우 호출되는 핸들러입니다.
  • 21번 줄, Submit 핸들러를 등록합니다.
  • 24번 줄, input에 사용자가 값을 입력할 경우 호출되는 핸들러를 등록합니다.

Controlled components의 input, textarea, select의 값이 state로 컨트롤 됩니다. 또한 사용자가 값을 입력할 경우, 이벤트 핸들러가 호출되어 setState로 state를 수정하여 태그 값을 바꾸게 됩니다.

사용자가 값을 입력할 경우, 매번 이벤트 핸들러를 호출하기 때문에, Controlled components는 사용자의 입력 값을 수정하거나, 유효 검사가 편리합니다.

handleChange(event) {
  this.setState({value: event.target.value.toUpperCase()});
}

예를 들면, 위의 코드처럼 사용자의 입력값을 항상 대문자가 되도록 할 수 있습니다.

2. textarea tag

HTML에서 textarea tag는 밑의 코드와 같이 사용합니다.

<textarea>
  이곳에 텍스트가 입력됩니다.
</textarea>

React에서는 value에 사용자의 입력값을 담게 됩니다. input과 형태가 유사합니다.

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'Please write an essay about your favorite DOM element.'
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('An essay was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <textarea value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen으로 예제 확인하기

3. select tag

HTML에서 select tag는 밑의 코드와 같이 사용됩니다.

<select>
  <option value="first">첫번째</option>
  <option value="second">두번째</option>
  <option value="third" selected>세번째</option>
</select>

React에서는 textarea 태그와 마찬가지로 value에 사용자의 입력 값을 담습니다.

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite La Croix flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen으로 예제 확인하기

4. 여러 input 핸들링 하기

HTML에서 여러개의 input, textarea, select를 사용할 수 있는 것처럼, React도 여러개의 input, textarea, select를 사용할 수 있는 것은 당연합니다!

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

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

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

CodePen으로 예제 확인하기

  • 4~7번 줄, input의 value로 쓰일 state를 정의합니다.
  • 9번 줄, 사용자가 값 입력시 호출되는 이벤트 핸들러의 this를 바인딩 해줍니다.
  • 12~20번 줄, 사용자 입력 값을 setState로 state에 저장합니다.
  • 18번 줄, input이 여러개가 존재할 경우 input의 값을 저장하기 위해 각각의 handle를 등록하지 않아도 됩니다.
    [name]을 사용하면 계산되어진 값을 변수 이름으로 사용할 수 있습니다. 계산되어진 이름을 가지는 변수에 값을 저장 할 수 있게 됩니다. 즉, target.name이 저장하고 있는 이름의 state에 값을 저장합니다. (ES6에서 추가되었습니다. Computed property names 참고)
  • 31번 줄, checkbox 타입의 input의 값이 변경 될 때 호출되는 이벤트 핸들러를 등록합니다.
  • 40번 줄, input에 값을 입력 할 경우 호출되는 이벤트 핸들러를 등록합니다.

참고

'React.JS' 카테고리의 다른 글

[React.JS] Composition VS Inheritance  (0) 2017.04.25
[React.JS] Lifting State Up  (0) 2017.04.24
[React.JS] List와 Key  (0) 2017.04.18
[React.JS] Handling Events  (0) 2017.04.07
[React.JS] State와 Lifecycle  (0) 2017.04.06
댓글
공지사항
최근에 올라온 글