티스토리 뷰

HTML에서 form은 자체적인 상태를 가지고 있고, 리액트와 조금 다르게 동작함.

만약 name을 입력받는 form이 있을 경우, 사용자가 form을 제출하면 새로운 페이지로 이동하는 기본 HTML form 동작을 수행한다.

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

 

하지만 대부분 Javascript function으로 form의 제출을 처리하고 사용자가 form에 입력한 데이터에 접근하도록 하는 것이 편리, 제어컴포넌트라는 기술을 이용함.

 

제어 컴포넌트(Controlled Component)

HTML에서 input, textarea, select와 같은 form element는 일반적으로 사용자의 입력을 기반으로 state를 관리하고 업데이트 함. 

React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며, setState()에 의해 업데이트 됨.

React state를 "신뢰 가능한 단일 출처"(single source of truth)로 만들어 두 요소(html의 form element와 React의 state)를 결합할 수 있다. 그렇게 되면 form을 Rendering하는 React Component는 form에 발생하는 사용자 입력값을 제어함. 이러한 방식으로 React에 의해 값이 제어되는 입력 form element를 제어 컴포넌트라고 함.

 

이전 예시가 전송될 때 이름을 기록하기 원한다면 form을 제어 컴포넌트로 작성할 수 있음.

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

React state의 value는 form element에 설정되므로 표시되는 값은 항상 input태그의 value가 되고 이는 신뢰 가능한 단일 출처(single source of truth)가 된다.

이렇게 제어컴포넌트를 사용하면 input값은 항상 React state에 의해 결정된다.

 

textarea태그

text를 child로 정의한다.

<textarea>는 value attribute를 대신 사용,

<textarea>를 사용하는 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>
    );
  }
}

 

select 태그

<select>태그는 드럽다운 목록을 만든다.

아래코드와 작성하여 selected 옵션과 같이 사용할 수 있다.

* selected 옵션 : 초기값, 기본값 지정하는 select 태그의 옵션

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

 

위의 <input> <textarea> <select>모두 비슷하게 동작하고 제어컴포넌트를 구현하는데 value를 사용한다. 

 

file input 태그

사용자가 하나 이상의 파일을 server에 업로드 하거나 file api를 통하여 js로 조작할 수 있다.

읽기전용이므로 React에서는 비제어 컴포넌트이다.

<input type="file" />

 

 

다중입력제어

여러 input element를 제어해야 할 때 각 element에 name 속성을 추가하여 e.target.name값을 통해 handler가 어떤 작업을 할 지 선택할 수 있게 해준다.

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

 

이러한 제어 컴포넌트로 모든 입력상태를 연결해야 하므로 코드가 복잡해질 수 있다.

이러한 경우 폼을 구현하기 위한 대체 기술인 비제어 컴포넌트가 있다.

이건 다음에 알아보자 ^------------------^

 

그리고 유효성검사, 방문한 필드추적 및 폼 제출 처리와 같은 복잡해질 Logic을 해결하기 위해 "Formik"을 사용할 수 있다. 요거도 다음에 알아보자 ^--------------------------------------------------------------------^

 

 

참고 : ko.reactjs.org/docs/forms.html

 

폼 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
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
글 보관함