Form Control

Jung taeWoong·2021년 5월 23일
1

React.js

목록 보기
11/19
post-thumbnail

Form Control

입력값을 받는 element들에게 value값으로 state를 걸어주고 setState() 메서드를 사용하여 상태를 변경하는 이벤트 핸들러를 만들어 이벤트를 걸어준다.

class FormControl extends React.Component {
  state = {
    value: '',
  }

  handleChange = (e) => {
    this.setState({ value: e.target.value })
  }

  render() {
    return (
      <input 
        value={this.state.value}
        onChange={this.handleChange}
        />
    )
  }
}

Controlled 컴포넌트

React 컴포넌트는 폼을 통해 입력된 사용자의 값을 제어 할 수 있다.
React를 통해 값이 관리되는 입력 요소는 컨트롤 컴포넌트(Controlled Component)이다.

Controlled Component를 사용하면 모든 state의 업데이트는 연결 된 이벤트 리스너에 의해 처리 된다.
Controlled Component를 통해 사용자의 입력 내용을 업데이트 하거나, 유효성검사 수행이 가능하다.

멀티 이벤트 핸들링

하나 이상의 <input />을 하나의 리스너로 컨트롤 할 수 있다.
여러 개의 컨트롤을 제어하기 위해서는 name 속성을 설정해야 한다.

class MultiControlInputs extends Component {
  state = {
    user: {
      email: '',
      password: ''
    }
  }

// 멀티 이벤트 핸들링 리스너
  handleChange = (e) => {
    const {name, value} = e.target
    
    // user 상태 업데이트
    this.setState({
      user: {
        ...this.state.user,
        [name]: value
      }
    })
  }
  
  render() {
    const { user: { email, password } } = this.state;
    
    return (
      <>
        <input
          type="email"
          name="email"
          aria-label="계정 이메일"
          value={email}
          onChange={this.handleChange} />
        <input
          type="password"
          name="password"
          aria-label="계정 패스워드"
          value={password}
          onChange={this.handleChange} />
      </>
	)
  }
}

TextArea Controll

React는 <textarea>요소의 사용자가 입력한 내용을 value 속성으로 받는다.

  <textarea 
    value={this.state.value}
    onChange={this.handleChange}
  />

Select Controll

React는 value 속성을 사용해 초기값을 설정

  <select
    className="react-select"
    value={this.state.value}
    onChange={this.handleChange}
  >
  <option value="">선택</option>
  // this.state.value가 "react"이면 초기 값으로 설정됨
  <option value="react">리액트</option> 
  <option value="reactRouter">리액트 라우터</option>
  <option value="redux">리덕스</option>

Multiple Select Controll

React는 <select> 요소에 다음의 2가지 설정이 요구된다.
1. multiple 속성값은 true
2. vlaue 속성값은 배열 데이터 유형으로 설정

  <select
    className="react-select"
    // multiple 속성은 true
    multiple={true}
    // this.state.value가 배열(Array)데이터 형식 이여야함
    value={this.state.value}
    onChange={this.handleChange}
  >
  <option value="">선택</option>
  <option value="react">리액트</option> 
  <option value="reactRouter">리액트 라우터</option>
  <option value="redux">리덕스</option>
 state = {
   value : [], // 초기값 배열
 }
	
handleChange(e) {
  // select > option 요소 수집 후 배열 데이터로 변경
  const options = Array.from(e.target.children)
  // 사용자가 선택한 option filtering
  const selectedOptions = options.filter(option => option.selected);
  // filtering 된 option.value 값을 아이템으로 하는 새로운 배열 반환
  const selectedOptionValue = selectedOption.map(option => option.value);
  // 상태 업데이트
  this.setState({value: selectedOptionValue});
}

Uncontrolled 컴포넌트

컨트롤 되지 않은 컴포넌트는 React 외부에서 작동되는 것처럼 처리된다.
사용자가 폼 입력 컨트롤(input, dropdown 등)에 입력하면 업데이트 된 정보가 React에서 별도 처리 과정 없이 요소에 바로 반영된다.

특별한 경우를 제외하고, 폼 컨트롤은 React에서 제어(Controlled)하는 것이 권장

File input element

<input type="file" />

이 컴포넌트는 프로그래밍 방식으로 값을 설정할 수 없고, 사용자에 의해 값이 설정되는 특별한 경우로 Uncontrolled 컴포넌트이다.
컨트롤 할 수 없는 컴포넌트는 React가 아닌, DOM 자체에서 데이터를 다뤄야 한다.
Uncontrolled 컴포넌트를 제어하기 위해 직접 DOM을 통해 요소의 사용자 입력값을 가져와 처리해야한다.
문제는 "가상 DOM에서 어떻게 실제 DOM에 접근할 것인가?"이다.

DOM 노드 참조

ref 속성은 컴포넌트가 렌더링 된 이후의 실제 DOM 노드나 React 요소에 접근해야할 때 사용하는 방법이다.

참조(Ref.)생성

ref속성을 활용하려면 먼저 React.createRef() 메서드를 사용해 참조 객체를 생성해야 한다.
생성 된 참조(Ref.)는 ref속성을 통해 DOM 노드 또는 React 요소를 가리킨다.

class FileInput extends Component {
  // 참조 객체 생성
  fileInput = React.createRef(null);

  handleSubmit = (e) => {
    e.preventDefault();
    console.log(`선택된 파일: ${this.fileInput.current.files[0].name}`);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        /* React에서는 for 속성을 htmlFor로 사용 */
        <label htmlFor="fileInput">
          /* 참조 할 노드의 ref 속성에 참조 객체 연결 */
          <input id="fileInput" type="file" ref={this.fileInput} />
        </label>
      </form>
    )
  }
}

참조(Ref.)접근

ref속성이 설정 된 DOM 요소는 ref.current속성을 통해 접근가능

  • React v16.8 부터는 useRef() 훅을 사용해 함수형 컴포넌트에서도 ref 속성 사용가능
import React, {useRef} from 'react';

const FunctionalComponent = (props) => {
  const divRef = useRef(null);
  
  return (
    <div ref={divRef}> ... </div>
  )
}
profile
Front-End 😲

0개의 댓글