Передача местоположения и pageContext со страницы дочерним компонентам в Gatsby - PullRequest
0 голосов
/ 28 мая 2020

Мой макет страницы для сайта Gatsby выглядит следующим образом:

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>
);

В дочернем компоненте:

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, как я могу исправить свой код, чтобы он работал?

Ответы [ 2 ]

0 голосов
/ 28 мая 2020

В итоге я использовал useLocation из @reach/router для возврата местоположения в дочерних компонентах. И я просто передаю pageContext как опору в <Breadcrumbs />, поскольку он используется только один раз и не передается ни в какие дочерние компоненты.

0 голосов
/ 28 мая 2020

Вместо использования 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 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...