React/TypeScript: HOC를 사용한 컨텍스트 소비 문제 해결하기
React와 TypeScript를 사용하는 경우, HOC를 사용하여 컨텍스트 소비를 구현할 때 어려움을 겪을 수 있습니다. 이 블로그 포스트에서는 React 16.3과 TypeScript 2.8에서 이 문제를 해결하는 과정을 안내합니다.
문제 이해
해결책에 도전하기 전에 문제를 이해해보겠습니다. React 문서에서 HOC를 사용하여 컨텍스트를 소비하는 예제를 제공합니다. 그들의 매뉴얼에서의 코드 스니펫은 다음과 같습니다:
const ThemeContext = React.createContext('light');
export function withTheme(Component) {
return function ThemedComponent(props) {
return (
<ThemeContext.Consumer>
{theme => <Component {...props} theme={theme} />}
</ThemeContext.Consumer>
);
};
}
이제 이 예제를 TypeScript로 구현하려고 하면 다음 줄에서 오류가 발생할 수 있습니다:
export default withTheme(ThemedButton);
TypeScript 컴파일러는 다음과 같은 오류 메시지로 불평합니다:
Argument of type 'typeof ThemedButton' is not assignable to parameter of type 'new () => Component<ThemedButtonProps, ThemedButtonState, any>'
이 오류는 타입이 올바르게 일치하지 않아 발생하며, 분노를 유발할 수 있습니다. 우리는 이 문제를 해결하기 위해 해결책에 대해 알아보겠습니다.
해결책
문제를 해결하기 위해 코드를 약간 수정해야 합니다. 첫째로, Component
대신 React.ComponentType<Props>
을 사용하여 클래스 컴포넌트와 함수형 컴포넌트를 모두 수용합니다. 이 수정은 서명의 호환성을 보장합니다.
다음이 업데이트된 withTheme
함수입니다:
export function withTheme<P extends ThemeAwareProps>(Component: React.ComponentType<P>) {
return function ThemedComponent(props: Pick<P, Exclude<keyof P, keyof ThemeAwareProps>>) {
return (
<ThemeContext.Consumer>
{theme => <Component {...props} theme={theme} />}
</ThemeContext.Consumer>
);
};
}
또한, ThemedButton
컴포넌트를 약간 수정해야 합니다. 어떠한 props와 state도 지정하지 않고 React.Component
를 확장하는 대신, props와 state의 유형을 명시적으로 정의해야 합니다.
interface ThemedButtonProps extends ThemeAwareProps {
}
interface ThemedButtonState {
}
class ThemedButton extends React.Component<ThemedButtonProps, ThemedButtonState> {
// ...
}
이러한 수정을 통해 오류가 해결되고, HOC를 사용하여 컨텍스트를 의도대로 소비할 수 있게 됩니다.
결론
이 블로그 포스트에서는 React와 TypeScript에서 HOC를 사용하여 컨텍스트 소비 문제를 해결하는 방법에 대해 논의했습니다. 제공한 해결책을 따르고 필요한 조정을 하면 React 애플리케이션에서 HOC 패턴을 사용하여 컨텍스트를 성공적으로 소비할 수 있습니다. 즐거운 코딩하세요!
참고자료:
– React 문서: HOC를 사용하여 컨텍스트 소비하기
– Dev.to: TypeScript, React, 그리고 HOC
참고 자료 :
https://stackoverflow.com/questions/50612299/react-typescript-consuming-context-via-hoc
같은 카테고리의 다른 글 보기 :