[React 디자인 패턴] Controlled vs Uncontrolled Components

지은·2023년 6월 14일
1

⚛️ React

목록 보기
21/23

제어 컴포넌트 (Controlled Components)

: React 컴포넌트의 상태(state)에 의해 값이 제어되는 폼 요소
e.g. input, textarea, select ...

  • Controlled Component를 사용할 때는 React 컴포넌트의 상태를 업데이트하여 값을 변경하고, 이 값을 폼 요소에 props로 전달한다.
    그리고 사용자의 입력에 응답하여 상태를 업데이트한다.
  • 이 방식은 React의 단방향 데이터 흐름을 따르며, React 컴포넌트가 폼 요소의 상태를 완벽하게 제어한다.
  • 변경된 input value가 매번 상태(state)로 업데이트되므로, Input의 value와 React의 value가 항상 최신의 값으로 일치함이 보장된다.
  • 입력값의 유효성 검사, 변경 이벤트 처리, 상태 관리 등을 더 세밀하게 제어할 수 있다.
const ControlledForm = () => {
  const [nameInputError, setNameInputError] = useState("");
  const [name, setName] = useState("");

  useEffect(() => {
    if (name.length < 2) {
      setNameInputError("Name must be two or more characters");
    } else {
      setNameInputError("");
    }
  }, [name]);

  return (
    <form>
      <p>{nameInputError}</p>
      <input
        name="name"
        type="text"
        placeholder="Name"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button>Submit</button>
    </form>
  );
};

비제어 컴포넌트 (Uncontrolled Components)

: React 컴포넌트의 상태(state)에 의해 값이 제어되지 않는 폼 요소

  • Uncontrolled Component를 사용할 때는 React 컴포넌트의 상태를 업데이트하지 않고, DOM의 직접적인 참조를 통해 값을 가져오거나 업데이트한다.
  • 이 방식은 React 컴포넌트가 폼 요소의 상태를 완전히 제어하지 않으므로, 상태 관리의 일부를 DOM에 위임한다.
  • 일반적으로 사용자가 입력을 직접 제어하거나, 특정 상황에서만 값을 가져올 때 유용하다.
  • 유효성 검사, 상태 관리 등을 구현하기 어려울 수 있다.
const UncontrolledForm = () => {
  const nameInput = useRef();

  const handleSubmit = (e) => {
    console.log(nameInput.current.value);
    e.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="name" type="text" placeholder="Name" ref={nameInput} />
      <input type="submit" value="Submit" />
    </form>
  );
};
제어 컴포넌트비제어 컴포넌트
React가 값을 관리DOM이 값을 저장
사용자의 입력이 항상 state로 push입력값이 필요할 때, element에서 pull
React가 값이 항상 일치함을 보장값이 항상 일치함을 보장하지 않음
리렌더링이 발생리렌더링이 발생하지 않음

Controlled vs Uncontrolled Form


Controlled vs Uncontrolled Modal

App.js

App() {
  const [shouldShowModal, setShouldShowModal] = useState(false);

  return (
    <>
      <h3>UncontrolledModal</h3>
      <UncontrolledModal>This is uncontrolled modal.</UncontrolledModal>
      
      <h3>ControlledModal</h3>
      <ControlledModal
        shouldShow={shouldShowModal}
        onRequestClose={() => setShouldShowModal(false)}
      >
        This is controlled modal.
      </ControlledModal>
      <button onClick={() => setShouldShowModal(true)}>Show Modal</button>
    </>
  );
}

UncontrolledModal.js

비제어 모달 컴포넌트는 모달의 상태(shouldShow) 컴포넌트 내부에서 자체적으로 관리한다.

const UncontrolledModal = ({ children }) => {
  const [shouldShow, setShouldShow] = useState(false);

  return (
    <>
      <button onClick={() => setShouldShow(true)}>Show Modal</button>
      {shouldShow && (
        <ModalBackground onClick={() => setShouldShow(false)}>
          <ModalBody onClick={(e) => e.stopPropagation()}>
            <button onClick={() => setShouldShow(false)}>X</button>
            {children}
          </ModalBody>
        </ModalBackground>
      )}
    </>
  );
};

ControlledModal.js

제어 모달 컴포넌트는 모달의 상태(shouldShow)를 부모 컴포넌트로부터 props로 받아와 제어한다.

const ControlledModal = ({ shouldShow, onRequestClose, children }) => {
  return shouldShow ? (
    <ModalBackground onClick={onRequestClose}>
      <ModalBody onClick={(e) => e.stopPropagation()}>
        <button onClick={onRequestClose}>X</button>
        {children}
      </ModalBody>
    </ModalBackground>
  ) : null;
};

이 글은 아래 링크를 참고하여 작성한 글입니다.
Controlled vs Uncontrolled Components | React Design Pattern -3

profile
개발 공부 기록 블로그

0개의 댓글