Form[React]

SnowCat·2023년 1월 6일
0

React - Main Concepts

목록 보기
8/11
post-thumbnail

※ 공식문서를 읽고 정리한 글입니다.

제어 컴포넌트

<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>
  • 우리가 알고 있는 html의 form과 동일하게 값을 받아 이벤트를 발생시키게 된다
  • 그런데 입력값이 바뀔때마다 특수문자를 제거하는 등의 값을 제어해야하는 경우 어떻게 해야할까?
  • 이럴때 React의 방식으로 값을 제어할 수 있게 해주는 것이 제어 컴포넌트이다.
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에 의해 입력값이 제어되는 컴포넌트를 제어 컴포넌트라고 부름
  • input의 value값을 this.state.value로 설정해 React가 form의 input을 제어할 수 있게 해준다
  • 이 때 React state는 신뢰 가능한 단일 출처(single source of truth)가 됨
  • 키 입력은 handleChange()에 전달되고 메서드는 값을 입력한 값과 동일하게 출력하게 됨
  • 제어 컴포넌트를 사용하면 코드가 길어지는 대신 다른 UI엘리먼트에 input값을 전달하거나 다른 event handler에서 값을 재설정할 수 있게 됨

제어 컴포넌트의 활용

1. textarea

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>
    );
  }
}
  • textarea 태그는 여러줄의 텍스트 입력을 받는 태그로, 텍스트를 child로 가짐
  • React에서는 텍스트를 value 속성에 가지게 되며, 이 값을 제어하는 컴포넌트를 생성 가능
    예문에서는 제어 컴포넌트를 활용해 <textarea>태그를 <input>태그처럼 활용함

2. 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>
    );
  }
}
  • html에서는 selected 속성을 사용했지만, React에서는 앞선 예시들과 비슷하게 value 속성을 <select> 태그에 사용함 => 제어 컴포넌트에서 사용하기 편리
<select multiple={true} value={['B', 'C']}>
  • 2개 이상의 값을 제어할 경우 <select> 태그에 multiple옵션을 true로 설정해주면 됨

여러개의 input 제어

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 //key값에 표현식을 지정하는 Computed Property Name
    });
  }

  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>
    );
  }
}
  • 컴포넌트 내에 제어하는 변수가 2개 이상이여도 각각을 제어 가능
  • setState()는 state값을 병합하기 때문에 바뀐 부분만 다시 호출됨

Nul이 들어가면?

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

setTimeout(function() {
  ReactDOM.createRoot(mountNode).render(<input value={null} />);
}, 1000);
  • setState()에 null이나 undefined가 들어가면 setState()가 작동하지 않음
    예문에서는 첫번째 입력이 일어난 이후 입력이 들어가게 됨

제어 컴포넌트를 사용하기 싫으면?

  1. 비제어 컴포넌트
  2. Formik

출처:
https://ko.reactjs.org/docs/forms.html

profile
냐아아아아아아아아앙

0개의 댓글