在这里做出新反应并尝试将我的头缠在新的Context API上(我还没有研究过Redux等。)
似乎我可以做很多我想做的事,但最终我会得到很多提供商,所有提供商都需要一个标签来包装我的主应用程序。
我将为Auth提供一个提供程序,一个为主题提供服务,一个为聊天消息提供服务(通过Pusher.com访问),等等。另外,使用React Router的还有另一个包装元素。
我要结束这个(还有更多)吗?...
<BrowserRouter>
<AuthProvider>
<ThemeProvider>
<ChatProvider>
<App />
</ChatProvider>
</ThemeProvider>
</AuthProvider>
</BrowserRouter>
还是有更好的方法?
答案 0 :(得分:1)
免责声明:我从未使用过,只是进行了研究。
FormidableLabs(他们为许多OSS projects做出了贡献)有一个名为react-context-composer
的项目似乎可以解决您的问题。
React正在提出一个新的Context API。 API鼓励撰写。 该实用程序组件有助于在组件保持代码清洁 将呈现多个上下文提供者和使用者。
答案 1 :(得分:1)
如果您想要一种无需任何第三方库即可组成Provider的解决方案,请使用带有Typescript批注的解决方案:
// Compose.tsx
interface Props {
components: Array<React.JSXElementConstructor<React.PropsWithChildren<any>>>
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,当然可以删除注释。
答案 2 :(得分:0)
一个简单的解决方案是使用类似于compose函数的方法 https://github.com/reduxjs/redux/blob/master/src/compose.js,并将所有提供程序合并在一起。
provider.js
const Providers = compose(
AuthProvider,
ThemeProvider,
ChatProvider
);
我还没有使用这个解决方案,但是有了React的新钩子功能,您可以使用react钩子在函数定义中访问它,而不是呈现您的上下文。
答案 3 :(得分:0)
很少的代码行可以解决您的问题。
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)
}
答案 4 :(得分:0)
使用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>
答案 5 :(得分:0)
如果需要将外部 props 注入到 provider elemet 使用 withprops hoc,请重新编写 js 嵌套助手