React와 TypeScript로 구현한 동적 폼 생성기 개발 — 4개월간의 시행착오와 성공 사례
긴 글, 핵심만 먼저 — 이 글을 3줄로 정리해드려요.
동적 폼 생성기는 다양한 데이터 입력을 유연하게 처리할 수 있는 유용한 도구다. React와 TypeScript를 사용해 이를 구현하는 과정에서 여러 시행착오를 겪었다. 이 글에서는 그 경험을 공유하고, 직면한 문제와 해결 방법을 정리해보겠다.
프로젝트 초기 설정
프로젝트를 시작할 때, React와 TypeScript의 조합은 매우 매력적이었다. 강력한 타입 시스템 덕분에 코드의 안정성을 높일 수 있었고, React의 컴포넌트 기반 구조는 동적 폼을 구현하는 데 적합했다. 그러나 초기 설정 과정에서 몇 가지 고민이 필요했다.
TypeScript의 설정 파일인 tsconfig.json을 적절하게 구성하는 것이 중요하다. 특히, strict 모드를 활성화하면 타입 체크가 엄격해지므로, 코드 작성 시 더 많은 주의가 필요하다. 예를 들어, strictNullChecks를 활성화하면 null이나 undefined를 명확하게 처리해야 하므로, 코드의 복잡도가 증가할 수 있다.
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true,
...
}
}
동적 폼 구조 설계
동적 폼의 핵심은 사용자 입력에 따라 폼 필드가 변경되는 것이다. 이를 위해서는 폼 필드의 상태를 관리하는 구조가 필요하다. 처음에는 상태를 단순한 객체로 관리했지만, 복잡한 폼 구조에서는 상태 관리가 어려워졌다.
리액트의 useState 훅을 사용해 각 필드의 상태를 관리할 수 있지만, 상태가 깊어질수록 업데이트 로직이 복잡해졌다. 이때 useReducer 훅을 고려해보는 것이 좋다. useReducer를 통해 상태 업데이트 로직을 명확하게 분리하고, 상태 변화에 대한 예측 가능성을 높일 수 있었다.
const initialState = { fields: [] };
function reducer(state, action) {
switch (action.type) {
case 'ADD_FIELD':
return { ...state, fields: [...state.fields, action.payload] };
case 'REMOVE_FIELD':
return { ...state, fields: state.fields.filter( field. !== action.) };
:
state;
}
}
[state, dispatch] = (reducer, initialState);