Не удалось найти «хранилище» в контексте «Подключения (компонента)» GatsbyJS Redux

#reactjs #redux #gatsby

#reactjs #redux #gatsby

Вопрос:

Я столкнулся с некоторыми проблемами с моим веб-приложением Gatsby при попытке реализовать хранилище для глобальных состояний с помощью Redux. Я новичок в обоих. Раньше я работал с MobX и «простым» React.

Проблема в том, что я не могу получить доступ к данным моего хранилища из своих компонентов. Я использую класс Redux Provider, как я читал в нескольких руководствах, но поскольку я использую и других поставщиков, мой случай кажется особенным… Это то, что я придумал до сих пор:

gatsby-ssr.js и gatsby-browser.js

 import prepPages from "./prepPages"
export const wrapRootElement = prepPages
  

prepPages.js

 import React from "react"
import { createGlobalStyle, ThemeProvider } from "styled-components"
import { Provider } from "react-redux"
import createStore from "./src/state/store"
import { MDXProvider } from "@mdx-js/react"
import { Table } from "./src/components"
import Theme from "./src/themes/theme"

//Provider for my global styling
const GlobalStyles = createGlobalStyle`...`

//Overriding the table component
const components = {
  table: Table
}

export default ({ element }) => {
  const store = createStore()
  return(
    <Provider store={store}>
      <MDXProvider components={components}>
        <ThemeProvider theme={Theme}>
          <GlobalStyles/>
            {element}
        </ThemeProvider>
      </MDXProvider>
    </Provider>
    )
}
  

store.js

 import {createStore as reduxCreateStore} from "redux"

const initialState = {
  loggedIn: false,
  menuToggleOn: false,

  //other initial states
}

const reducer = (state, action, dispatch) => {
  //Toggles
  if(action.type === 'TOGGLE_MENU'){
    return {
      ...state,
      toggleMenuOn: !state.toggleMenuOn
    }
  }
  //other actions
}

const createStore = () => reduxCreateStore(reducer, initialState);
export default createStore;
  

components/Nav.js

 import React from 'react';
import {useStaticQuery, Link, graphql} from "gatsby";
import {NavWrapper} from "../styles";
import { Button } from "./Button";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faBars} from "@fortawesome/free-solid-svg-icons";
import connect from "react-redux/lib/connect/connect";
import PropTypes from "prop-types"

const NavHolder = ({loggedIn, toggleMenu, toggleMenuOn}) => {
  ...
  //defining the nav items depending on the login state
  var items;
  var cta = {};
  if(loggedIn){
    items = [
      {name: "home", ref: "/", key: 0},
      {name: "wiki", ref: "/wiki", key: 1},
      {name: "workspace", ref: "/workspace", key: 2}
    ]
  }else {
    items = [
      {name: "about", ref: "#about", key: 0},
      {name: "features", ref: "#features", key: 1},
      {name: "download", ref: "#download", key: 2},
      {name: "contact", ref: "#contact", key: 3}
    ];
    cta = {exists: true, name: "login"}
  }
  //mapping the nav items and adding the visible class if the menu is toggled on
  let navItems = items.map((item) =>
    <li key={item.key} className={toggleMenuOn ? "nav-item visible" : "nav-item"}>
      <a href={item.ref} className={isActive ? "active":""}>
        {item.name}
      </a>
    </li>
  )
  return (
    <NavWrapper>
      <ul>
        <li>
          <Link to="/" id="logo">...</Link>
        </li>
        {navItems}
        <li className="nav-toggle">
          <a href="/" onClick={toggleMenu}>
            <FontAwesomeIcon icon={faBars}/>
          </a>
        </li>
        {cta.exists amp;amp; (
          <li className="nav-cta">
            <Button color="petrol" href="login">{cta.name}</Button>
          </li>
        )}
      </ul>
    </NavWrapper>
  )
}
NavHolder.propTypes = {
  loggedIn: PropTypes.bool.isRequired,
  menuToggleOn: PropTypes.bool.isRequired,
  toggleMenu: PropTypes.func.isRequired
}
const mapStateToProps = ({loggedIn, toggleMenuOn}) => {
  return { loggedIn, toggleMenuOn }
}
const mapDispatchToProps = dispatch => {
  return { toggleMenu: () => dispatch({ type: `TOGGLE_MENU` }) }
}

const ConnectedNav = connect(mapStateToProps, mapDispatchToProps)(NavHolder)

export const Nav = () => {
  return <ConnectedNav/>
}
  

Я думал, что это может сработать, но я получаю эту ошибку:

Ошибка: не удалось найти «хранилище» в контексте «Connect (NavHolder)». Либо оберните корневой компонент в Provider, либо передайте поставщику пользовательского контекста React поставщику и соответствующему потребителю контекста React для подключения (NavHolder) в параметрах подключения.

не удалось найти хранилище в компоненте ошибка

Кто-нибудь знает, где я ошибся? Я действительно благодарен за любую помощь. Спасибо 🙂

Ответ №1:

С Gatsby вам нужно использовать wrapRootElement API.

Оберните корневой элемент в разметку Gatsby один раз, используя wrapRootElement, API, поддерживающий как рендеринг сервера Gatsby, так и процессы JavaScript браузера.

Обратитесь к Добавлению хранилища Redux в Gatsby docs, для этого есть пример репозитория.

Комментарии:

1. Я не использую это в gatsby-ssr.js и gatsby-browser.js так же, как это делает репозиторий GitHub?