반응형
해당 게시글에서 훅 내부의 리듀서를 오버라이딩 하는 방법을 배웠다.
때로는 훅 내부의 상태를 전적으로 외부에서 관리하고 싶을 수 있다.
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?
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
반응형
'FrontEnd' 카테고리의 다른 글
리액트 디자인패턴 : Render Props(렌더 프롭스 패턴) (0) | 2022.06.02 |
---|---|
리액트 성능 최적화 : Code Splitting(코드 스플리팅) (0) | 2022.06.02 |
리액트 디자인패턴 : State Reducer Pattern (스테이트 리듀서 패턴) (0) | 2022.06.01 |
리액트 디자인패턴 : Prop Collections and Getters (프롭 컬렉션 엔 게터 패턴) (0) | 2022.06.01 |
리액트 디자인패턴 : Compound Components (컴파운드 컴포넌트 패턴) (0) | 2022.06.01 |