본문 바로가기

FrontEnd

리액트 디자인패턴 : Control Props (컨트롤 프롭스 패턴)

반응형

State-Reducer-Pattern

 

리액트 디자인패턴 : State Reducer Pattern (스테이트 리듀서 패턴)

IOC : 제어의 역전 https://itchallenger.tistory.com/261?category=1063253 제어의 역전(IOC : Inversion of Control) in React 원문 보기 사용 중인 루틴에 기능을 추가해달라는 요청을 받게 되면? 리액트 컴포..

itchallenger.tistory.com

해당 게시글에서 훅 내부의 리듀서를 오버라이딩 하는 방법을 배웠다.

때로는 훅 내부의 상태를 전적으로 외부에서 관리하고 싶을 수 있다.

TLDR :

  • State Reducer 패턴과 동일하게 리듀서 오버라이딩
  • onChange 콜백을 이용해 외부 상태관리 지원

패턴 설명

<input/> 컴포넌트를 생각해보자
해당 컴포넌트는 내부에서 value가 관리된다 (event.target.value)

// 내부의 상태를 캡슐화하는 input
function MyCapitalizedInput() {
  const [capitalizedValue, setCapitalizedValue] = React.useState('')

  return (
    <input
      value={capitalizedValue}
      onChange={e => setCapitalizedValue(e.target.value.toUpperCase())}
    />
  )
}​

하지만 value에 state를 외부에서 주입하여 사용하는 것도 가능하다.

function MyTwoInputs() {
  const [capitalizedValue, setCapitalizedValue] = React.useState('')
  const [lowerCasedValue, setLowerCasedValue] = React.useState('')

  function handleInputChange(e) {
    setCapitalizedValue(e.target.value.toUpperCase())
    setLowerCasedValue(e.target.value.toLowerCase())
  }

  return (
    <>
      <input value={capitalizedValue} onChange={handleInputChange} />
      <input value={lowerCasedValue} onChange={handleInputChange} />
    </>
  )
}​

이 경우 MyCapitalizedInput에서 Control Props Pattern을 구현하여,
상위 컴포넌트에 외부 상태(input)와 onChange를 제공할 것을 제안한다.

이때 외부의 onChange와 내부 컴포넌트(MyCapitalizedInput)의 onChange의 시그니처를 일치시키는 것이 핵심이다.

How?

 

UI 이미지

State Reducer와 차이점

readOnly 파라미터

  • 외부 상태가 주어진 경우, readOnly가 false인데 onChange가 주어지지 않으면 useToggle 훅은 해당 상태를 변경할 수 없음을 알린다.
    • onChange가 없으면 readOnly나 마찬가지이다.

onChange 함수

  • 외부에서 관리하는 상태를 변경하기 위해 사용한다.
  • onChange의 시그니처는 (state,action)=>void
  • void인 이유는 해당 리듀서를 이용해 dispatch하지 않을 것이기 때문이다.
    • 하지만 useToggle 훅의 reducer와 호환된다.

on (외부 변수)

  • on을 제공하는 경우 onChange와 함께 핸들러를 리듀서 타입에 맞춰준다.
  • on을 제공하지 않는 경우는 onChange는 불필요하다.
    • useToggle의 상태를 사용할 것이기 때문이다.

사용자가 해당 컴포넌트를 오용하지 못하도록 경고

아래와 같은 경우 warning을 제공한다.

  • readOnly===false인데 onChange를 전달하지 않은 경우
    • useToggle Hook은 해당 상태를 변경할 수 없다. 따라서 onChange를 전달하도록 경고한다.
  • on 값이 이상하게 변화 1 : (boolean =>undefined 또는 null)
  • on 값이 이상하게 변화 2 : (undefined 또는 null=>boolean)

원래 리코일이 context API를 완전히 대체할 것이라 생각했는데,

위와 같이 컴포넌트 라이브러리의 라이프사이클에 커스터마이징을 끼워넣으려면, context API나 리덕스 아니면 어려울 것 같다.

참고자료

the implementation of the useControlledSwitchWarning

 

GitHub - reach/reach-ui: The Accessible Foundation for React Apps and Design Systems

The Accessible Foundation for React Apps and Design Systems - GitHub - reach/reach-ui: The Accessible Foundation for React Apps and Design Systems

github.com

 

반응형