ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 리액트에서 다중의 동적 폼 처리하기
    React.js & Next.js 2023. 6. 15. 20:04

    들어가며

    프론트엔드로 개발하게 될 경우, 정적으로 사전에 생성된 폼 데이터를 다루기도 하지만, 동적으로 추가하거나 제거 및 수정이 필요한 폼을 만들어야 하는 경우가 생깁니다.

     

    스타일링 코드를 제거하고 자바스크립트 코드 위주로 동적 폼 처리에 대한 기본적인 흐름을 파악합니다.

    예시 [wanted] 동적 폼 처리 뷰

    원티드의 동적 폼 예시

    코드

    import React, { useEffect, useState } from 'react';
    
    function DynamicFormComponent() {
      const [formFields, setFormFields] = useState([{ name: '', value: '' }]);
    
      const handleAddFields = () => {
        const values = [...formFields, { name: '', value: '' }];
        setFormFields(values);
      };
    
      const handleRemoveFields = (index: number) => {
        if (formFields.length === 1) {
          alert('At least one form must remain');
          return;
        }
        const values = [...formFields].splice(index, 1);
        setFormFields(values);
      };
    
      const handleInputChange = (index: number, e: React.ChangeEvent<HTMLInputElement>) => {
        const values = [...formFields];
    
        if (e.target.name === 'name') {
          values[index].name = e.target.value;
        } else {
          values[index].value = e.target.value;
        }
        setFormFields(values);
      };
    
      const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        console.log(formFields);
      };
    
      useEffect(() => {
        console.log('formFields changed:', formFields);
      }, [formFields]);
    
      return (
        <form onSubmit={handleSubmit} style={{ padding: '2%' }}>
          {formFields.map((field, index) => (
            <div key={index} style={{ marginBottom: 5 }}>
              <input
                type='text'
                placeholder='Field name'
                name='name'
                value={field.name}
                onChange={(e) => handleInputChange(index, e)}
                style={{ marginRight: 10 }}
              />
    
              <input
                type='text'
                placeholder='Field value'
                name='value'
                value={field.value}
                onChange={(e) => handleInputChange(index, e)}
                style={{ marginRight: 10 }}
              />
    
              <button type='button' onClick={() => handleRemoveFields(index)}>
                Remove
              </button>
            </div>
          ))}
    
          <button
            type='button'
            onClick={() => handleAddFields()}
            style={{ marginTop: 10, marginRight: 10 }}
          >
            Add Field
          </button>
    
          <button type='submit'>Submit</button>
        </form>
      );
    }
    
    export default DynamicFormComponent;
    

    함수 설명

    handleAddFields

      const handleAddFields = () => {
        const values = [...formFields, { name: '', value: '' }];
        setFormFields(values);
      };
    
    • 필드를 동적으로 추가합니다
    • useState로 관리하고 있는 formFields를 스프레드(…)연산자를 통해 값만 복사하여, 빈 객체 ( {name:’’, value: ‘’} )를 추가합니다
    • 이후 setState를 통해 values를 덮어씌웁니다

    handleRemoveFields

      const handleRemoveFields = (index: number) => {
        if (formFields.length === 1) {
          alert('At least one form must remain');
          return;
        }
        const values = [...formFields].splice(index, 1);
        setFormFields(values);
      };
    
    • formField를 최소한 1개를 유지하기 위한 방어코드를 추가했습니다
    • 그렇지 않을경우 스프레드(…) 연산자를 통해 값만 복사한 새로운 배열에서 해당 인덱스를 제거합니다.
    • 이후 setState를 통해 values를 덮어씌웁니다

    handleInputChange

      const handleInputChange = (index: number, e: React.ChangeEvent<HTMLInputElement>) => {
        const values = [...formFields];
    
        if (e.target.name === 'name') {
          values[index].name = e.target.value;
        } else {
          values[index].value = e.target.value;
        }
        setFormFields(values);
      };
    
    • if 조건문을 통해 분기를 나눴습니다
      • e.target.name 이 ‘name’ 일 경우 해당 index에 따른 value값을 객체의 name 속성에 재할당합니다
      • e.target.name 이 ‘value’ 일 경우 해당 index에 따른 value값을 객체의 value 속성에 재할당합니다
    • 이후 setState를 통해 values를 덮어씌웁니다

    결과 보기

    댓글

Designed by Tistory.