[React] Form

MinJi·2024년 8월 12일

FrontEnd

목록 보기
2/13

Controlled Components

  • React에서 변경 가능한 state는 일반적으로 컴포넌트의 state 속성에 존재하며, setState()로만 업데이트할 수 있다.
  • React state를 '신뢰 가능한 단일 소스'로 만들어 두 요소를 결합할 수 있다. 그런 다음 렌더링 되는 React 컴포넌트는 이후에 폼에서 밸생하는 유저 입력을 제어한다. 이 때 React에 의해 제어되는 Input 폼 요소를 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.toUpperCase()});
  }

  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>
    );
  }
}
  • value 속성은 폼 요소에 설정되므로 표시되는 값은 항상 this.state.value 가 되고 React state가 신뢰 가능한 소스가 된다.
  • React state를 업데이트하기 위해 모든 키스트로크에서 handleChange 가 동작하기 때문에 사용자가 입력할 때 표시되는 값이 업데이트된다.
  • 제어되는 컴포넌트를 사용하면 모든 state 변경과 연관되는 핸들러 함수가 생기고, 이를 통해 사용자 입력을 수정하거나 검증하는 것이 간단해진다.

제어되지 않는 컴포넌트

  • 각 state 업데이트를 위해 이벤트 핸들러를 작성하는 대신 DOM으로부터 폼의 값을 얻기 위해 ref를 사용할 수 있다.
  • React 렌더링 라이프사이클에서 form 요소의 value 속성은 DOM 값보다 우선시한다. 제어되지 않는 컴포넌트를 사용하는 경우 React가 초기값을 지정하고 후속 업데이트를 제어하지 않는 것이 좋다. -> defaultValue 속성을 지정한다.
render() {
  return (
    <form onSubmit={this.handleSubmit}>
      <label>
        Name:
        <input
          defaultValue="Bob"
          type="text"
          ref={(input) => this.input = input} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}

-> <input type="checkbox"><input type="radio"> 는 defaultChecked 를 지원한다.
-> <select><textarea> 도 defaultValue 를 지원한다.

태그

textarea 태그

  • React에서는 value 속성을 사용하여 텍스트를 정의한다.
    <textarea value={this.state.value} onChange={this.handleChange} />
    - this.state.value를 생성자 함수에서 초기화하기 때문에 일부 텍스트를 가진채로 text area를 시작할 수 있다.

예)

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 태그

  • selected 속성 대신 React에서는 루트 select 태그에 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>
    );
  }
}

여러 input 제어

  • 각 요소에 name 속성을 추가한 후 event.target.name 값을 기반으로 핸들러 함수를 고를 수 있다.

예)

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

0개의 댓글