#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?