강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

JEOUNG WOOYOUNG님의 프로필 이미지
JEOUNG WOOYOUNG

작성한 질문수

타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게

(해설) 제어 컴포넌트 - 유저 정보

폼테그 다른 태그를 하나의 상태 객체로 묶기

작성

·

19

0

폼을 만들 때
input, textarea, radio, checkbox 같이 태그 종류가 달라도
하나의 객체 상태로 묶어서 관리하는 방식으로 만들어 보았습니다만
실무에서나 보통은 하나씩 만드는지 아니면 이것또한 정답이 없는지 궁금합니다!

아니면 상황에 따라 상태를 나누는 기준이 따로 있는지도 궁금합니다.

답변 2

1

수코딩님의 프로필 이미지
수코딩
지식공유자

안녕하세요 🙂

리액트에서 폼을 구현할 때 input, textarea, radio, checkbox처럼 서로 다른 태그들을 하나의 객체 상태로 묶어서 관리하는 방식이 적절한지에 대한 고민은 실무에서도 자주 등장합니다. 이 방식이 옳은지, 혹은 각각의 상태를 분리해서 관리하는 것이 더 좋은지에 대해서는 하나의 정답이 존재한다고 보기는 어렵습니다. 다만 상황과 목적에 따라 더 적합한 선택지는 분명히 존재합니다.

먼저 여러 폼 요소를 하나의 객체 상태로 관리하는 방식에 대해 살펴보겠습니다. 폼은 본질적으로 사용자가 입력한 값들의 집합이기 때문에, 이를 하나의 객체로 묶어 관리하는 것은 개념적으로 매우 자연스럽습니다. 예를 들어 다음과 같이 상태를 정의할 수 있습니다.

const [form, setForm] = useState({
  title: '',
  content: '',
  category: '',
  agree: false,
});

이 코드에서는 제목, 내용, 카테고리, 동의 여부와 같은 여러 입력값을 form이라는 하나의 객체로 관리합니다. 실무에서는 이 객체를 그대로 서버에 전달하는 경우가 많기 때문에, API 연동 시에도 효율적인 구조입니다.

이 방식에서 중요한 부분은 공통 onChange 핸들러를 사용하는 것입니다.

const handleChange = (e) => {
  const { name, value, type, checked } = e.target;

  setForm(prev => ({
    ...prev,
    [name]: type === 'checkbox' ? checked : value,
  }));
};

이 코드는 모든 입력 요소의 변경 이벤트를 하나의 함수로 처리합니다. name 속성을 통해 어떤 필드가 변경되었는지를 구분하고, checkbox의 경우에는 checked 값을, 그 외의 입력 요소는 value 값을 상태에 반영합니다. 이를 통해 태그 종류에 관계없이 일관된 방식으로 폼 상태를 관리할 수 있습니다.

객체로 폼 상태를 관리하는 방식의 장점은 폼 전체가 하나의 의미 단위로 묶인다는 점입니다. 구조를 이해하기 쉽고, 제출 시에도 별도의 가공 없이 바로 사용할 수 있습니다. 반면 일부 값만 변경되더라도 객체 전체를 복사해야 하므로, 폼이 매우 커질 경우에는 상태 업데이트 코드가 다소 복잡해질 수 있다는 단점도 존재합니다.

다음으로 상태를 각각 분리해서 관리하는 방식입니다.

const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const [agree, setAgree] = useState(false);

이 방식은 각 입력값이 독립적인 상태를 가지도록 합니다. 어떤 값이 어떤 상태인지 명확하게 드러나기 때문에 직관적이며, 필드 수가 적거나 각 입력값이 서로 다른 로직을 가질 경우에는 관리하기가 수월합니다. 다만 필드가 늘어날수록 상태 선언과 이벤트 핸들러가 함께 증가하게 되고, 최종 제출 시에는 다시 하나의 객체로 묶어야 하는 번거로움이 발생할 수 있습니다.

실무에서는 상태를 나누는 기준을 몇 가지 관점에서 판단합니다. 첫째, 해당 값들이 논리적으로 하나의 폼 데이터를 구성하는지 여부입니다. 하나의 제출 단위를 가진다면 객체로 묶는 것이 적절합니다. 둘째, 값들이 함께 변경되는지 여부입니다. 대부분 동시에 변경되고 함께 사용된다면 하나의 상태로 관리하는 편이 효율적입니다. 셋째, 폼의 복잡도입니다. 단순한 폼이라면 객체 하나로 충분하지만, 조건부 렌더링이나 복잡한 검증 로직이 많다면 다른 관리 방식이 필요할 수 있습니다.

폼의 규모가 더 커지고 상태 변화 규칙이 복잡해질 경우에는 useReducer를 사용하는 패턴도 자주 활용됩니다.

const reducer = (state, action) => {
  switch (action.type) {
    case 'CHANGE':
      return {
        ...state,
        [action.name]: action.value,
      };
    default:
      return state;
  }
};

이 방식은 상태 변경 로직을 reducer 함수에 모아 관리할 수 있기 때문에, 복잡한 폼에서도 상태 흐름을 예측하기 쉽다는 장점이 있습니다.

정리하자면, 서로 다른 폼 태그들을 하나의 객체 상태로 묶어서 관리하는 방식은 충분히 정석적인 접근이며, 실무에서도 가장 많이 사용되는 패턴 중 하나입니다. 다만 모든 상황에 동일하게 적용해야 하는 규칙은 아니며, 폼의 역할과 복잡도에 따라 상태를 분리하거나 관리 방식을 확장하는 것이 바람직합니다. 결국 중요한 것은 특정 패턴을 고집하는 것이 아니라, 현재 상황에서 가장 읽기 쉽고 유지보수하기 좋은 구조를 선택하는 것입니다.

항상 정말 감사드립니다

0

안녕하세요, 인프런 AI 인턴입니다. JEOUNG WOOYOUNG님.

폼의 여러 요소들을 하나의 상태 객체로 묶어서 관리하는 방법에 대해 질문 주셨네요. 이는 개발 시 유연하고 효율적으로 상태를 관리할 수 있는 방법 중 하나입니다.

객체로 상태를 묶어 관리하는 장점:

  1. 코드 간소화: 여러 개의 폼 요소 상태를 하나의 객체로 관리하면 코드가 깔끔해지고 유지보수가 쉬워집니다.
  2. 상태 관리의 용이성: 하나의 상태 객체로 모든 폼 데이터를 관리하면, 모든 업데이트나 변경 사항이 쉽게 트래킹되고 관리될 수 있습니다.
  3. 데이터 구조화: 폼 데이터를 서버로 전송할 때 더욱 자연스럽게 구조화된 데이터를 전달할 수 있습니다.

하지만 상황에 따라 고려해야 할 점도 있습니다:

  • 복잡성: 매우 복잡한 폼이거나 독립적으로 나누어 관리해야 할 필요가 있는 경우, 개별적인 상태 관리가 더 나을 수 있습니다.
  • 성능 고려사항: 하나의 큰 객체 상태가 변경될 때마다 컴포넌트가 리렌더링되므로, 큰 양의 데이터가 있을 경우 성능 문제가 발생할 수 있습니다.

상황에 따른 상태 관리 기준:

  • 단순한 폼: 하나의 객체로 묶어서 관리하는 것이 대체로 유리합니다.
  • 복잡하거나 독립적인 섹션을 가진 폼: 각 섹션이나 태그별로 상태를 나누는 것이 나을 수 있습니다. 특히 복잡한 유효성 검사가 필요한 경우, 개별 관리가 용이합니다.

관련된 추가 정보를 원하시면 다음의 질문들을 참고해 보시면 도움이 될 것입니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

JEOUNG WOOYOUNG님의 프로필 이미지
JEOUNG WOOYOUNG

작성한 질문수

질문하기