-
[React / React Native] 각종 Provider들의 역할만들기 2019. 11. 27. 13:21
현재 진행중인 React Native 프로젝트 개발 환경을 세팅하던 중, 문득 React를 하다보면 자주 볼 수 있는 Provider들이 어떤 역할을 하는지 궁금해져서 잠깐 정리 해봤습니다.
우선 styled-components 에서 사용하는 ThemeProvider부터 살펴보면
export interface DefaultTheme {} export interface ThemeProviderProps<T extends object, U extends object = T> { children?: React.ReactNode; theme: T | ((theme: U) => T); } export type BaseThemeProviderComponent< T extends object, U extends object = T > = React.ComponentClass<ThemeProviderProps<T, U>>; export type ThemeProviderComponent< T extends object, U extends object = T > = BaseThemeProviderComponent<AnyIfEmpty<T>, AnyIfEmpty<U>>; export const ThemeProvider: ThemeProviderComponent<AnyIfEmpty<DefaultTheme>>; // NOTE: this technically starts as undefined, but allowing undefined is unhelpful when used correctly export const ThemeContext: React.Context<AnyIfEmpty<DefaultTheme>>; export const ThemeConsumer: typeof ThemeContext["Consumer"];
생각보다 별게 없네요 ㅎㅎ;;
그럼 다음은 apollo-client 에서 사용하는 ApolloProvider
import React from 'react'; import ApolloClient from 'apollo-client'; export interface ApolloProviderProps<TCache> { client: ApolloClient<TCache>; children: React.ReactNode | React.ReactNode[] | null; } export declare const ApolloProvider: React.FC<ApolloProviderProps<any>>;
역시 코드가 길지 않습니다.
둘이 하는 역할이 동일하고, 단순히 원하는 타입의 Props를 받아서 children 에게 전파하는 역할만 담당하게 됩니다.
실제 사용하는 코드를 보면,
// 여러 파일에서 일부분만 복붙한 코드입니다. 그냥 쓰시면 동작하지 않습니다 ㅠㅠ interface IProps { initialThemeType?: ThemeType; children?: React.ReactElement; } function CustomApolloProvider({ initialThemeType, children }: IProps): React.ReactElement { const { state } = useAppContext() let token: string | undefined = undefined if (state.user && state.user.token) token = state.user.token return <ApolloProvider client={getClient(token)}>{children}</ApolloProvider> } function CustomThemeProvider({ children, initialThemeType = defaultThemeType, }: Props): React.ReactElement { const [themeType, setThemeType] = useState(initialThemeType); const changeThemeType = (): void => { const newThemeType = themeType === ThemeType.LIGHT ? ThemeType.DARK : ThemeType.LIGHT; setThemeType(newThemeType); }; const theme = createTheme(themeType); return ( <Provider value={{ changeThemeType, themeType, theme, }} > <ThemeProvider theme={theme}>{children}</ThemeProvider> </Provider> ); } const RootProviders = ({ initialThemeType, children }: Props): React.ReactElement => { return ( <AppProvider> <CustomThemeProvider initialThemeType={ initialThemeType === ThemeType.LIGHT ? ThemeType.LIGHT : undefined } > <CustomApolloProvider>{children}</CustomApolloProvider> </CustomThemeProvider> </AppProvider> ); }; export default RootProviders;
이런 식으로 자식 컴포넌트 안에서 apolloClient / theme 속성을 사용할 수 있게 해줍니다.
[맘먹고 정리 하려다가 생각보다 별게 없어서 허무하게 끝난 포스팅....]