[SoundLink] 복잡한 Props 구조, 컴포넌트 전달 방식으로 리팩토링

강수영·2025년 6월 22일
0

1. 문제 상황

InputField.tsx 컴포넌트는 label, input, button을 함께 렌더링하는 구조인데, 특정 상황에서는 버튼이 필요 없는 경우도 있어 조건에 따라 버튼 렌더링을 제어해야 했습니다.

// 버튼이 필요한 경우 InputField 사용 예시

<InputField
	// InputField의 기본 props
  id="id"
  label="아이디"
  placeholder="아이디를 입력해 주세요"
  onChange={handleChange}
  message={validationStatus.message}
  isValid={validationStatus.isValid}

  // 버튼 관련 props
  isPending={isPending} // 버튼 로딩 상태
  buttonText="중복확인" // 버튼에 표시할 텍스트
  buttonEnabled={validationStatus.isValid} // 버튼 활성화 여부
  onClick={() => mutate()} // 버튼 클릭 시 실행할 함수
/>

그런데 버튼을 렌더링해야 할 경우 넘겨야 하는 props가 많아지면서, 구조가 점점 복잡해졌습니다.


2. 구조 개선 시도

버튼이 필요한 경우 넘겨야 할 props가 점점 많아지면서, InputField 컴포넌트가 본래의 역할 이상으로 많은 책임을 지게 되었습니다.

그래서 고민 끝에, 버튼 관련 props를 모두 개별로 넘기는 대신, 버튼 컴포넌트 자체를 props로 전달하는 방식으로 구조를 개선해보기로 했습니다.

// 버튼 관련 props를 InputField에 직접 넘기지 않고,
// 버튼 컴포넌트를 분리해 actionButton props로 전달한 경우

<InputField
  // InputField의 기본 props
  ...

  // 버튼 컴포넌트를 직접 전달
  actionButton={
    <LoadingSpinnerButton
      isPending={isPending} // 버튼 로딩 상태
      buttonText="중복확인" // 버튼에 표시할 텍스트
      buttonEnabled={validationStatus.isValid} // 버튼 활성화 조건
      onClick={() => mutate()} // 클릭 시 실행할 함수
/>
  }
/>

// InputField.tsx 내부 (컴포넌트 정의)
interface InputFieldProps extends React.InputHTMLAttributes<HTMLInputElement> {
  // ...기타 input 관련 props
  actionButton?: React.ReactNode; // 버튼 컴포넌트 직접 전달
}

export default function InputField({
  ...,
  actionButton,
  ...props
}: InputFieldProps) {
  return (
    <div className="...">
      <label htmlFor={id}>{label}</label>

      <div className="flex gap-2">
        <Input id={id} {...props} />
        {actionButton && <div>{actionButton}</div>}
      </div>
    </div>
  );
}

이처럼 버튼을 직접 넘기는 방식으로 구조를 변경하면서, InputField는 본래의 역할인 입력 필드 렌더링에만 집중할 수 있게 되었고, 버튼 로직은 별도 컴포넌트에서 자유롭게 관리할 수 있게 되었습니다.


3. 정리

버튼 컴포넌트를 직접 넘기는 방식으로 구조를 개선하면서 다음과 같은 이점을 얻을 수 있었습니다.

  • InputField는 입력 필드 렌더링에만 집중할 수 있게 되었고,
  • 버튼 관련 로직은 외부에서 자유롭게 관리할 수 있게 되었습니다.
  • 버튼의 동작이나 UI가 상황에 따라 달라질 때도 유연하게 대응할 수 있습니다.

복잡했던 props 구조를 단순화하고, 컴포넌트 간 책임도 더 명확하게 나눌 수 있었습니다.

profile
프론트엔드 개발자

2개의 댓글

comment-user-thumbnail
2025년 6월 27일

끝내주는 기능 더 만들어주세요

1개의 답글