我的盖茨比网站的页面布局是这样的。
const Container = ({location, children, pageContext}) => {
return (
<>
<Header location={location} />
<Breadcrumbs pageContext={pageContext} />
{children}
<Footer />
</>
)
}
我需要通过 location
和 pageContext
从页面到子组件。我曾试着添加 location
和 pageContext
至 DataProvider
像这样。
export const DataContext = React.createContext();
const DataProvider = ({ children, location, pageContext }) => {
return (
<DataContext.Provider value={{
location,
pageContext
}}>
{children}
</DataContext.Provider>
)
};
export default DataContext
export { DataProvider }
然后我用 DataProvider
在 gatsby-ssr.js
和 gatsby-browser.js
像这样。
export const wrapRootElement = ({ element }) => (
<ThemeProvider theme={theme}>
<DataProvider>
{element}
</DataProvider>
</ThemeProvider>
);
In the child component:
const HeaderLinks = () => {
return (
<DataContext.Consumer>
{
context => (
<Menu
theme="light"
mode="horizontal"
selectedKeys={[context.location.pathname]}
>
<Menu.Item key={key}>
<Link to={url}>{name}</Link>
</Menu.Item>
</Menu>
)
}
</DataContext.Consumer>
)
}
但这似乎并不奏效,因为当我移动到另一个页面时,它并没有被更新。(我也有 wrapPageElement
与 Container
可能是这个原因。)
如何才能通过 location
和 pageContext
到子组件?是使用React Context还是简单地将它们作为道具传递?如果我应该使用React Context,我如何修正我的代码以使其工作?
而不是使用 wrapRootElement
使用 ContexProvider
你可以利用 wrapPageElement
在这里你可以获得页面道具并将它们传递给DataProvider。这将确保pageContext和位置在每个页面上发生变化。
export const wrapRootElement = ({ element }) => (
<ThemeProvider theme={theme}>
{element}
</ThemeProvider>
);
export const wrapPageElement = ({ element, props }) => (
<DataProvider value={props}>
{element}
</DataProvider>
);
export const DataContext = React.createContext();
const DataProvider = ({ children, value }) => {
const {location, pageContext} = value;
return (
<DataContext.Provider value={{
location,
pageContext
}}>
{children}
</DataContext.Provider>
)
};
export default DataContext
export { DataProvider }
我最后用的是 useLocation
从 @reach/router
来返回子组件的位置。而我只是简单地将 pageContext
作为道具 <Breadcrumbs />
因为它只使用一次,而且不会传递给任何子组件。