본문 바로가기

클라이언트/React
[리액트(React)] Form

// Form

- 사용자로부터 입력을 받기 위한 형식

- 모든 데이터를 state에서 관리하기 때문에 관리가 용이하다.

- 사용자의 입력을 직접적으로 제어 가능하다.

- <form>, <input>, <textarea>, <select> 등의 태그를 사용한다.

- <label> 을 사용할 때, 일반 자바스크립트와 다르게 for=""이 아니라 htmlFor=""을 사용한다.

<label htmlFor="email">Email</label>

// input 양방향 바인딩

1. useState()

2. useRef()
    - 값을 깔끔하게 설정하는 것이 어렵기 때문에 권장하진 않는다.

3. FormData


// useState

1. 초기값을 useState로 선언한다.

const [playerName, setPlayerName] = useState(initialName);

- 여러 개의 값을 binding 해야 하면, 객체로 선언하여 하나의 value로 관리할 수도 있다.


2. state 값을 변경할 함수를 선언한다.

function handleNameChange(event) {
  setPlayerName(event.target.value);
}


- 사용자가 입력한 값은 event.target.value로 받아올 수 있다.


3. input 태그에 onChange를 추가한다.

<input
  type="text"
  required
  value={playerName}
  onChange={handleNameChange}
/>


- state값을 value로 설정한다.


import React, { useState } from 'react';

function SignUp(props) {
  const [name, setName] = useState('');

  const handleChangeName = (event) => {
    setName(event.target.value);
  };

  const handleSubmit = (event) => {
    alert(`이름: ${name}`);
    event.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit} style={{ margin: 20, display: 'flex' }}>
      <label style={{ marginRight: 5 }}>
        <span style={{ marginRight: 5 }}>이름: </span>
        <input type='text' value={name} onChange={handleChangeName} />
      </label>
      <button type='submit' style={{ marginTop: 2, paddingTop: 2 }}>
        제출
      </button>
    </form>
  );
}

export default SignUp;

// useRef

1. ref변수를 선언한다.

const ref변수명 = useRef();

2. input의 속성으로 ref를 설정한다.

function handle함수명() {
  const 변수 = 참조변수명.current.value
}

import { useRef } from 'react';

export default function Login() {
  const email = useRef();
  const password = useRef();

  function handleSubmit(event) {
    event.preventDefault();
    console.log(email.current.value);
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Login</h2>

      <div className="control-row">
        <div className="control no-margin">
          <label htmlFor="email">Email</label>
          <input id="email" type="email" name="email" ref={email} />
        </div>

        <div className="control no-margin">
          <label htmlFor="password">Password</label>
          <input id="password" type="password" name="password" ref={password} />
        </div>
      </div>

      <p className="form-actions">
        <button className="button button-flat">Reset</button>
        <button className="button">Login</button>
      </p>
    </form>
  );
}

// FormData

1. input 태그에 name 속성을 설정한다.

<input name="name속성1" />
<select name="name속성2">

2. FormData 객체를 생성한다.

const 변수명 = new FormData(event.target);

- event.target을 매개변수로 보낸다.

3. FormData에서 특정 입력값을 가져온다.

const FormData변수 = new FormData(event.target);

// 한 개
const 특정입력값 = 변수명.get('name속성');	

 //여러 개
const 입력값들객체 = Object.fromEntries(FormData변수.entries());
입력값들객체.같은name이여러개인입력값 = FormData변수.getAll('name속성');


- 여러 입력값을 관리하려면 브라우저에 내장된 Object 클래스를 사용한다.

- Object 클래스를 사용하면 체크박스와 같이 이름이 같은 값이 여러 개인 input은 제외되기 때문에 추가로 받아와야 한다.


export default function Signup() {
  function handleSubmit(event) {
    event.preventDefault();

    const fd = new FormData(event.target);
    const data = Object.fromEntries(fd.entries());
    data.acquisition = fd.getAll('acquisition');
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Welcome on board!</h2>
      <p>We just need a little bit of data from you to get you started 🚀</p>

      <div className="control">
        <label htmlFor="email">Email</label>
        <input id="email" type="email" name="email" />
      </div>

      <div className="control-row">
        <div className="control">
          <label htmlFor="password">Password</label>
          <input id="password" type="password" name="password" />
        </div>

        <div className="control">
          <label htmlFor="confirm-password">Confirm Password</label>
          <input
            id="confirm-password"
            type="password"
            name="confirm-password"
          />
        </div>
      </div>

      <hr />

      <div className="control-row">
        <div className="control">
          <label htmlFor="first-name">First Name</label>
          <input type="text" id="first-name" name="first-name" />
        </div>

        <div className="control">
          <label htmlFor="last-name">Last Name</label>
          <input type="text" id="last-name" name="last-name" />
        </div>
      </div>

      <div className="control">
        <label htmlFor="phone">What best describes your role?</label>
        <select id="role" name="role">
          <option value="student">Student</option>
          <option value="teacher">Teacher</option>
          <option value="employee">Employee</option>
          <option value="founder">Founder</option>
          <option value="other">Other</option>
        </select>
      </div>

      <fieldset>
        <legend>How did you find us?</legend>
        <div className="control">
          <input
            type="checkbox"
            id="google"
            name="acquisition"
            value="google"
          />
          <label htmlFor="google">Google</label>
        </div>

        <div className="control">
          <input
            type="checkbox"
            id="friend"
            name="acquisition"
            value="friend"
          />
          <label htmlFor="friend">Referred by friend</label>
        </div>

        <div className="control">
          <input type="checkbox" id="other" name="acquisition" value="other" />
          <label htmlFor="other">Other</label>
        </div>
      </fieldset>

      <div className="control">
        <label htmlFor="terms-and-conditions">
          <input type="checkbox" id="terms-and-conditions" name="terms" />I
          agree to the terms and conditions
        </label>
      </div>

      <p className="form-actions">
        <button type="reset" className="button button-flat">
          Reset
        </button>
        <button type="submit" className="button">
          Sign up
        </button>
      </p>
    </form>
  );
}