-
리액트에서 다중의 동적 폼 처리하기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개를 유지하기 위한 방어코드를 추가했습니다
- 그렇지 않을경우 스프레드(…) 연산자를 통해 값만 복사한 새로운 배열에서 해당 인덱스를 제거합니다.
- MDN.Array.prototype.splice()
- MDN.Array.prototype.filter()를 사용할 수도 있습니다
- 이후 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를 덮어씌웁니다
결과 보기
'React.js & Next.js' 카테고리의 다른 글
한번에 적용하는 Sentry with Next.js (1) 2023.10.23 구글 애널리틱스 (GA4) for developers (3) 2023.07.16 다양한 파일 확장자 파일 미리보기 지원하기 (0) 2023.04.05 input image 미리보기 구현하기 (0) 2023.03.31 빠르게 시작하는 드래그 앤 드롭 (0) 2023.03.26