코딩하는라민

[React] form 제어하기 본문

Core/React

[React] form 제어하기

코딩하는라민 2023. 2. 28. 00:15
728x90
반응형

[React] form 제어하기

 

📌 form

  • <input>, <textarea>, <select>와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트한다.

state 를 누가 관리하느냐에 따라 제어 컴포넌트와 비제어 컴포넌트로 나뉘게 된다.

element 를 가지고 있는 컴포넌트가 관리할 경우 제어 컴포넌트, element의 state 만 관리하지 않고 element 의 참조만 컴포트가 소유한다면 비제어 컴포넌트라고 할 수 있다.

<form onsubmit="handleSubmit()">
  <label>
    아이디 
    <input type="uerId" name="uerId" placeholder="abcd124" />
  </label>
  <button type="submit">비밀번호 찾기</button>
</form>

 

📌 제어 컴포넌트(Controlled component)

React 컴포넌트는 폼을 통해 사용자의 입력값을 제어할 수 있다.

컴포넌트의 state 를 '신뢰 가능한 단일 출처(Single Source of Truth)'로 만들어 HTML + React 요소를 결합해 사용할 수 있다.

 

이러한 폼 엘리먼트를 제어 컴포넌트라고 한다.

 

function Form(){
    const [state, setState] = useState({
        userID: ''
    })
    const handleSubmit=(e)=>{
        e.preventDefault();
        console.log(`${state.id} 를 입력하셨습니다.`)
    }
    const handleInput = (e) => {
        e.setState({
            userID: e.target.value
        })
    }
    const 
    return(
        <form onsubmit={handleSubmit}>
            <label>
                아이디 
                <input 
                    type="uerId" 
                    name="uerId" 
                    placeholder="abcd124"
                    onChange={handleInput} />
            </label>
            <button type="submit">확인</button>
        </form>
    )
}

 

✅ 신뢰 가능한 단일 출처

하나의 상태는 한 곳에서만 존재해야 한다.

 

📌 input

제어 컴포넌트로 사용하면 input 값은 state 에 의해 결정된다.

value 는 항상 {this.state.value} 가 된다.

 

...
const [state, setState] = useState('')
const handleChange = () => {
    setState('hello')
}

return (
    <form>
        <label />
        <input 
            type="text" 
            name="search" 
            value={state} 
            onSubmit={this.handleSubmit}
        />
        ...

value 는 input 의 입력값이다.

form 에서는 onSubmit 이벤트로 입력값의 변화를 핸들링할 수 있다.

콜백함수에는 setState 로 state 를 변경해줄 수 있다.

그 값이 다시 input 의 value 로 들어오게 되고, state 는 신뢰 가능한 단을 출처가 된다.

 

📌 textarea

input 과 마찬가지로 textarea 도 value 를 사용한다.

input 과 달리 textarea 는 일부 텍스트를 가진 채 시작된다는 차이점이 있다.

<textarea>
    내용을 입력해주세요.
</textarea>
import React, { useState } from 'react';

function Home() {
  const [contentState, setContentState] = useState('내용을 입력해주세요');
  const handleChangeTextArea = (e) => {
    setContentState(e.target.value);
    console.log('content' + contentState);
  };
  return (
    <form>
      <h2>content</h2>
      <textarea
        name="content"
        cols="30"
        rows="10"
        value={contentState}
        onChange={handleChangeTextArea}
      />
    </form>
  );
}

export default Home;

 

📌 select

<select>
    <option value="diary">Diary</option>
    <option value="review">Review</option>
    <option value="information">Information</option>
    <option selected value="study">Study</option>
    <option value="tip">Tip</option>
</select>
import React, { useState } from 'react';

function Home() {
  const [state, setState] = useState({
    content: '내용을 입력해주세요',
    value: 'review'
  });
  const handleChange = (e) => {
    const { name, value } = e.target;
    setState({
      ...state,
      [name]: value,
    });
  };
  return (
    <form>      
      <h2>content</h2>
      <select name="value" value={state.value} onChange={handleChange}>
        <option value="diary">Diary</option>
        <option value="review">Review</option>
        <option value="information">Information</option>
        <option selected value="study">Study</option>
        <option value="tip">Tip</option>
      </select>
      <textarea
        name="content"
        cols="30"
        rows="10"
        value={state.content}
        onChange={handleChange}
      />
      <button>제출하기</button>
    </form>
  );
}

export default Home;

 

📌 멀티 Input 을 하나의 이벤트로 핸들링하기

여러 개의 Input 을 컨트롤하려면 각각을 구별할 수 있는 name 을 설정해야한다.

하나의 핸들러로 설정하기 위해서 이벤트 핸들러는 1개만 설정해준다.

import React, { useState } from 'react';

function Home() {
  const [state, setState] = useState({
    today: '',
    todos: '',
  });
  const handleChange = (e) => {
    const { name, value } = e.target;
    setState({
      ...state,
      [name]: value,
    });
  };
  return (
    <form>
      <h2>today</h2>
      <label>
        <input
          name="today"
          type="text"
          value={state.today}
          onChange={handleChange}
        />
      </label>
      <h2>Todos</h2>
      <label>
        <input
          name="todos"
          type="text"
          value={state.todos}
          onChange={handleChange}
        />
      </label>
    </form>
  );
}

export default Home;
  1. input 요소에 name, value, event handler설정하기
    • 두 input 요소는 같은 event handler 함수를 갖기
    • value 에는 state 값이 들어간다.
  2. useState의 인자로 객체 받기
  3. setState 안의 ...state 는 모든 state 값(today, todos)이 들어간다.(객체복사)
    • 이 값들은 변화 없이 기본 값을 그대로 가져간다.
  4. e.target 을 name 과 value 로 비구조할당해서 각각 name과 value 를 변수명처럼 사용할 수 있다.
    • [name]: value 는 현재 선택한 요소의 name 과 value 를 업데이트한다.
  5. 이때, ...state 는 [name]: value 보다 뒤에 나오면 안 된다.
    • 리액트는 위에서부터 아래방향으로 흐르는데, ...state 가 뒤에 나오면 나중에 값이 앞의 값을 덮으므로 결국은 입력값에 상관 없이 전부 기본값이 나올 것이기 때문이다.
  6. 각각을 콘솔창에 출력해보면 사용자의 입력값을 잘 받는 것을 확인할 수 있다.

 

 

 

객체 초기자 - JavaScript | MDN

객체는 new Object(), Object.create() 또는 literal 표기법(initializer 표기법)을 사용해 초기화될 수 있습니다. 객체 초기자는 중괄호({})로 묶인 0개 이상의 객체의 프로퍼티명과 관련 값의 쌍을 콤마로 구

developer.mozilla.org

 

 

 

 


참고 : 리액트 공식 문서, 멋쟁이사자처럼 4기 yamoo9
  등을 공부하고, 간단하게 정리한 내용입니다. 잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.

728x90
반응형