IOC : 제어의 역전
https://itchallenger.tistory.com/261?category=1063253
자바는 익명 클래스의 메서드를 오버라이딩하여 파라미터로 넘기는 코딩이 있다. (요즘은 람다-문법적 설탕임.)
이는 특정 객체의 특정 메서드를 호출한다.
이는 js에서 콜백을 넘기는 것과 동일(isomorphic)하다.
제어의 역전이란 내 코드의 실행을 다른 API에 위임하는 것이다.
DI(의존성 주입)은 제어의 역전을 위해 내 코드조각을 집어넣는 것이다.
State Reducer Pattern
개발자가 default reducer의 특정 action type에 대한 동작을 오버라이딩 할 수 있도록 하는 패턴이다.
The State Reducer Pattern with React Hooks
How
1. 사용자에게 State의 타입, Action의 타입을 공개한다.
Action 타입과 리듀서 구현은 긴밀하게 연결되어있기 때문에, 허용하는 Action의 타입과 State의 타입을 제공할 필요가 있다.
export type ToggleAction =
| { type: "toggle" }
| { type: "reset"; initialState: ToggleState };
export interface ToggleState {
on: boolean;
};
또한 default 리듀서도 정의한다.
State Reducer의 시그니처는 관례에 따라 (prev:State,action:Action)=>(next:State)로 고정한다.
function toggleReducer(state: ToggleState, action: ToggleAction): ToggleState {
switch (action.type) {
case actionTypes.toggle: {
return { on: !state.on };
}
case actionTypes.reset: {
return action.initialState;
}
default: {
throw new Error(`Unsupported type`);
}
}
}
2. 개발자는 reducer를 정의하여 사용한다.
원래 reducer를 action type에 따라 개발자 입맛대로 오버라이딩하여 사용한다.
이때, 원래 reducer의 동작을 망치지 않도록 주의해서 사용해야 한다.
즉, 동적 타이핑 언어 입장에선, 내부 구현을 알아야 하는 내용 결합도가 발생한다.
타입스크립트라면 정해진 인터페이스 대로 reducer를 동작하도록 정의하면 되는 것이라 별 문제가 없을 듯 하다.
// ... import
const toggleStateReducer = (clickedTooMuch: boolean) =>
function toggleStateReducer(state: ToggleState, action: ToggleAction):ToggleState {
if (action.type === "toggle" && clickedTooMuch) {
return { on: state.on };
}
return toggleReducer(state, action);
};
function App() {
const [timesClicked, setTimesClicked] = React.useState(0);
const clickedTooMuch = timesClicked >= 4;
const { on, getTogglerProps, getResetterProps } = useToggle({
reducer: toggleStateReducer(clickedTooMuch)
});
return (
<div className="App">
<div className="App-header ">
<Switch
{...getTogglerProps({
disabled: clickedTooMuch,
on: on,
onClick: () => setTimesClicked((count) => count + 1)
})}
/>
{clickedTooMuch ? (
<div data-testid="notice">
Whoa, you clicked too much!
<br />
</div>
) : timesClicked > 0 ? (
<div data-testid="click-count">Click count: {timesClicked}</div>
) : null}
<button {...getResetterProps({ onClick: () => setTimesClicked(0) })}>
Reset!!!
</button>
</div>
</div>
);
}
export default App;
전체 코드는 아래에서 확인할 수 있다.
결론 :
state reducer pattern은 reducer를 오버라이딩 할 수 있도록 해준다.
'FrontEnd' 카테고리의 다른 글
리액트 성능 최적화 : Code Splitting(코드 스플리팅) (0) | 2022.06.02 |
---|---|
리액트 디자인패턴 : Control Props (컨트롤 프롭스 패턴) (0) | 2022.06.01 |
리액트 디자인패턴 : Prop Collections and Getters (프롭 컬렉션 엔 게터 패턴) (0) | 2022.06.01 |
리액트 디자인패턴 : Compound Components (컴파운드 컴포넌트 패턴) (0) | 2022.06.01 |
React children with typescript. 리액트 children 컴포넌트 타이핑 (0) | 2022.06.01 |