CombineProviders

 

함수로 구성 예시(비추천)

// combineProviders 유틸 함수 정의 import React, { ComponentProps, FC } from 'react'; export const combineProviders = (providers: FC[]): FC => { return providers.reduce( (Combined, CurrentProvider) => { return ({ children }: ComponentProps<FC>): JSX.Element => { return ( <Combined> <CurrentProvider>{children}</CurrentProvider> </Combined> ); }; }, ({ children }) => <>{children}</>, ); };
// 실제 중첩 사용 예시 export const Dispensing: NamedExoticComponent = memo(() => { const DispensingProviders = combineProviders([ DispensingAmountManagerProvider, IsOnDispensingProvider, IsRestDispensingProvider, ErrorProvider, ]); return ( <DispensingProviders> <DispensingScreen /> </DispensingProviders> ); });
이걸로 Screen Component 하나를 감싸는 경우에는 별 탈 없이 잘 사용하고 있었다.

문제점

내가 겪었던 문제점은 React-Native에서 React-navigation을 사용해서 화면 구성을 하는 경우에, nested stack을 구성하고자 하며, nested stack 진입 시 context를 구성하여 상태를 생성하고 스택이 종료되면 상태를 소멸시키고자 하는 경우였다.
이 경우 스택 첫 진입까진 괜찮은데 중첩 스택 내 화면에서 다른 화면으로 navigate를 시도하면 아래 그림과 같은 에러가 뜨면서 앱이 멈춰버리는 이슈가 있다.
notion image
 

HOC로 구성(추천)

역시 React는 순수하게 HOC로 중첩시켜주는 것이 가장 깔끔하다.
// CombineProviders HOC 유틸 컴포넌트 생성 import React, { FC } from 'react'; interface Props { providers: FC[]; } export const CombineProviders: FC<Props> = ({ providers, children }) => { return ( <> {providers.reduceRight( (acc, Provider) => ( <Provider>{acc}</Provider> ), children, )} </> ); };
// 실제 중첩 사용 예시 const Stack = createStackNavigator<TestStackParamList>(); export const TestStack = memo((): ReactElement => { return ( <CombineProviders providers={[ Provider1, Provider2, Provider3, Provider4, ]} > <Stack.Navigator ... > <Stack.Screen name='A' component={A} /> <Stack.Screen name='B' component={B} /> <Stack.Screen name='C' component={C} /> <Stack.Screen name='D' component={D} /> </Stack.Navigator> </CombineProviders> ); });