너무 많은 리액트 컨텍스트 제공자
새로운 Context API에 대해 고민하고 있습니다(Redux 등에 대해서는 아직 조사하지 않았습니다).
내가 해야 할 일의 대부분은 할 수 있을 것 같지만, 결국 메인 앱을 포장하기 위해 태그가 필요한 수많은 프로바이더와 함께 하게 될 것이다.
Auth 프로바이더, Theming 프로바이더, 채팅 메시지 프로바이더(Pusher.com 참조)를 준비합니다.또한 React Router를 사용하는 것도 래퍼 요소입니다.
결국 이것(그리고 더 많은 것)으로 끝나야 하나요?
<BrowserRouter>
<AuthProvider>
<ThemeProvider>
<ChatProvider>
<App />
</ChatProvider>
</ThemeProvider>
</AuthProvider>
</BrowserRouter>
아니면 더 좋은 방법이 있을까요?
서드파티 라이브러리가 없는 프로바이더를 위한 솔루션을 원하는 경우 Typescript 주석이 있는 솔루션을 다음에 제시합니다.
// Compose.tsx
interface Props {
components: Array<React.JSXElementConstructor<React.PropsWithChildren<unknown>>>
children: React.ReactNode
}
export default function Compose(props: Props) {
const { components = [], children } = props
return (
<>
{components.reduceRight((acc, Comp) => {
return <Comp>{acc}</Comp>
}, children)}
</>
)
}
사용방법:
<Compose components={[BrowserRouter, AuthProvider, ThemeProvider, ChatProvider]}>
<App />
</Compose>
Typescript를 사용하지 않으면 주석을 제거할 수 있습니다.
솔루션for
루프:
export const provider = (provider, props = {}) => [provider, props];
export const ProviderComposer = ({providers, children}) => {
for (let i = providers.length - 1; i >= 0; --i) {
const [Provider, props] = providers[i];
children = <Provider {...props}>{children}</Provider>
}
return children;
}
사용방법:
<ProviderComposer
providers={[
provider(AuthProvider),
provider(ThemeProvider),
provider(MuiPickersUtilsProvider, {utils: DateFnsUtils}),
]}
>
<App/>
</ProviderComposer>
@rista404의 답변을 사용합니다(https://stackoverflow.com/a/58924810/4035).
~하듯이react-context-composer
는 권장되지 않습니다.
@AO17님, ping 감사합니다.
면책사항:난 이걸 써본 적이 없어 그냥 조사했을 뿐이야.
많은 OSS 프로젝트에 공헌하고 있는 Freadable Labs에는 react-context-composer라는 프로젝트가 있습니다.
이것으로 당신의 문제가 해결된 것 같습니다.
React가 새로운 Context API를 제안하고 있습니다.API는 작곡을 장려합니다.이 유틸리티 컴포넌트는 컴포넌트가 여러 컨텍스트프로바이더와 컨슈머를 렌더링 할 때 코드를 깨끗하게 유지하는 데 도움이 됩니다.
몇 줄의 코드가 문제를 해결합니다.
import React from "react"
import _ from "lodash"
/**
* Provided that a list of providers [P1, P2, P3, P4] is passed as props,
* it renders
*
* <P1>
<P2>
<P3>
<P4>
{children}
</P4>
</P3>
</P2>
</P1>
*
*/
export default function ComposeProviders({ Providers, children }) {
if (_.isEmpty(Providers)) return children
return _.reverse(Providers)
.reduce((acc, Provider) => {
return <Provider>{acc}</Provider>
}, children)
}
이를 위한 간단한 해결책 중 하나는 Redux가 사용하는 것과 같은 구성 함수를 사용하여 모든 공급자를 결합하는 것입니다.그러면 compose 함수는 다음과 같이 호출됩니다.
const Providers = compose(
AuthProvider,
ThemeProvider,
ChatProvider
);
또한 저는 이 솔루션을 사용하지 않았지만 React의 새로운 후크 기능을 사용하여 컨텍스트를 렌더링하는 대신 리액트 후크를 사용하여 함수 정의에서 액세스할 수 있습니다.
프로바이더 elemet에 외부 소품을 삽입해야 하는 경우 js nest helper를 재구성합니다.
코멘트는 없지만 컴포넌트를 정리한rista404 답변을 통합하면 도움이 될 수 있습니다.useCallback()
훅을 사용하여 페이지 전환과 같은 경우에 컨텍스트 데이터 무결성을 보장합니다.
// Compose.tsx
interface Props {
components: Array<React.JSXElementConstructor<React.PropsWithChildren<any>>>
children: React.ReactNode
}
const Compose = useCallback((props: Props) => {
const { components = [], children } = props
return (
<>
{components.reduceRight((acc, Comp) => <Comp>{acc}</Comp>, children)}
</>
)
}, [])
export default Compose
언급URL : https://stackoverflow.com/questions/51504506/too-many-react-context-providers
'source' 카테고리의 다른 글
org. springframework.콩류.Unsupplicated Dependency Exception:이름이 'demoRestController'인 콩을 생성하는 동안 오류가 발생했습니다. (0) | 2023.04.04 |
---|---|
컨테이너 명령을 호출할 수 없습니다. (0) | 2023.04.04 |
Angular에서 정의된 text/ng-template를 사용하는 방법JS 지시어 (0) | 2023.04.04 |
Visual Composer 연결 미디어 파일 필요 (0) | 2023.04.04 |
사용자 역할에 따라 단일 보기에 서로 다른 내용 표시 (0) | 2023.04.04 |