React에서의 Form

https://facebook.github.io/react/docs/forms.html를 참조하여 작성했습니다.

Forms

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

우리가 알고 있는 기본적인 HTML 폼 형태이다. submit을 하게 되면 새로운 페이지로 넘어가게 되는 형태의 역할을 해주게 된다. React에서도 이렇게 그냥 사용해도 작동은 하게 된다. 하지만 Javascript에서는 Controlled components 방식으로 위와 같은 방식이 작동하도록 할 수 있다.

Controlled Components

React에서 <textarea>, <input>, <select> 같은 form elements는 사용자의 입력을 통한 뷰 변경과 데이터의 변경이 동시에 일어나는 특수한 element입니다. 이럴때 value prop이 있는 엘리먼트들을 React에서 값의 변경을 제어하며 이를 Controlled Components라 합니다.

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
  }
  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>
    );
  }
}

이런식의 예제를 보면 state.valuehandleChange에 의해 제어되고 handleSubmit을 통해 alert를 띄우게 됩니다. handleChange를 통해 입력값에 대한 여러가지 handle을 할 수 있게 됩니다.(validation 같은거..)

The Textarea Tag

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'Please write an essay about your favorite DOM element.'
    };
  }
  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>
    );
  }
}

이런식으로 위 input을 다루는 것과 비슷하게 value를 이용하여 변화를 감지하여 state를 변화시킵니다.

The select Tag

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};
  }
  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>
    );
  }
}

위 input, textarea와 똑같다.

Handling Multiple Inputs

만약 여러개의 input elements를 다뤄야 한다면 name attribute를 통해 변화를 감지해 주면 됩니다.

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };
  }
  handleInputChange = (event) => {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value; 
    //여기서 3항연산자를 통해 checkbox인 경우 checked만 체크. 아닌경우 밸류체크
    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>
    );
  }
}

Alternatives to Controlled Components

이런식으로 데이터를 다루는 것이 조금은 귀찮게 느껴질 수 있다.(리엑트가 아닌 라이브러리와 리엑트가 통신할 때 처럼..) 이럴때는 uncontrolled components라는 방법을 쓰는것을 추천한다. 링크, https://facebook.github.io/react/docs/uncontrolled-components.html