[react study] Form

hong·2021년 10월 29일

form element는 내부 state를 갖고있기 때문에
HTML form 은 다른 DOM element와는 약간 다르게 작동한다.
예를 들면, 이 form은 한개의 이름을 받는다.

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

이것을 React에 그대로 써도 작동은 하지만 대게 javascript function을 가지고 있으면 편리하다. 이를 위한 기술을 'controlled components'라고 한다.

  1. Controlled Components

React에서는 보통 변할 수 있는 state가 component의 state property에 저장되고,setState()로만 업데이트된다.

React state를 'single source of truth'로 만듦으로써 두개를 조합할 수 있다. 그러면 form을 render하는 React component는 뒤따르는 user input에 무엇이 일어날지 컨트롤한다. 이런 방식으로 React에 의해서 그 값이 컨트롤되는 input form element는 'controlled component'라고 불린다.

예제

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>
    );
  }
}

handleChange가 키를 누를때마다 React state를 업데이트 시키기 때문에 사용자가 입력할 때마다 보여지는 값이 업데이트된다.

  1. The textarea Tag
    HTML에서 textarea element는 자식요소의 text를 정의한다.
<textarea>
  Hello there, this is some text in a text area
</textarea>

React에서는 textarea는 attribute값을 사용한다. 이를 이용해서,<textarea>를 쓰면 한줄 input을 사용하는 form과 유사하게 만들 수 있다.

  
  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>
          Essay:
          <textarea value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

2.The select Tag

예제

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 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>
    );
  }
}  

select tag에 multiple 옵션을 넣어서 value attribute로 배열을 넣을 수 있다.

 <select multiple={true} value={['B', 'C']}> 
  1. The file input Tag
<input type="file" />

value가 readonly이기 때문에 React component로 조작이 불가능

  1. Handling Multiple Inputs

여러개의 input을 다루어야할 때, name attribute를 더할 수 있다. 그래서 event.target.name의 값을 이용해 handler function이 선택할 수 있게 할 수 있다.

예제

   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>
    );
  }
}
  1. Null 값 input
    controlled component 에서 value prop를 특성짓는 것은 유저가 input을 바꾸지 못하게한다. 만약 value값을 정해두었지만 input이 수정가능하게 하고싶다면 value값을 undefined나 null 값으로 설정해둘수있다.

예제 (이 input은 처음에는 잠겨있지만 조금의 딜레이 후에 수정 가능해진다.)

   ReactDOM.render(<input value="hi" />, mountNode);

setTimeout(function() {
  ReactDOM.render(<input value={null} />, mountNode);
}, 1000);

*mountNode 란 : document.getElementById('root') 같은 것..

profile
프론트엔드 개발을 하고 있습니다 ⌨️

0개의 댓글