从 Gatsby 应用程序的多个页面读取和写入 Redux 存储

Read and write to Redux store from multiple pages of a Gatsby App

我的应用是这样的:

盖茨比项目

index.tsx - 应用入口点 - 我调用

<Provider store={store}>
   <HomePage />
</Provider>

HomePage.js 使用 mapStateToProps 并使用 connect(mapStateToProps)(HomePage)

在我的主页中,我当然使用了多个 React 组件。我可以利用商店,read/write 上发生的任何事情 HomePage

在我的主页上,我有指向 ActivityPage 的链接。一旦我点击这个页面并登陆那里 - 问题就开始了。

ActivityPage利用多个子组件来完成任务。如何从 ActivityPage 访问 read/write?

我无法 useDispatch 从商店中写入甚至读取。我可以在我的 ReactDev 工具上看到商店,但是在尝试 read/write 时我得到 11 个错误,主要是我需要用 <Provider>

包装组件

我在 Stack Overflow 上阅读了不同的解决方案,这些解决方案建议我需要 mapStateToProps 并在我需要访问商店的任何组件上使用 connect

这不起作用,因为我特别希望从 'new page' 获得对商店的访问权。我需要去为我的子页面创建另一个商店吗?请帮助。 :

您的组件 必须 位于 redux Provider 组件内,以便使用 redux 挂钩 useSelectoruseDispatchconnect HOC.

在典型的 React 应用程序中,您会将 Provider 放在 App 组件中,这是所有内容的 parent。然而,Gatsby 使用不同的设置,其中每个页面都是完全独立的,因此没有共享 parent 我们可以放置 Provider.

Gatsby 的功能是 API 通过在配置文件中定义函数来覆盖自定义行为。您可以将一堆文件放在应用程序的根目录中,与 package.json 相同的文件夹中,但在 src 之外。我们将在这里使用的两个是 gatsby-browser.js, which controls the client-side, and gatsby-ssr.js, which controls the creation of static HTML pages through server-side rendering. Both of these files support a function called wrapRootElement.

我们使用 wrapRootElement 函数将我们的 Redux 提供程序作为每个页面的包装器放置。由于我们在两个文件中使用相同的函数,官方的“using-redux”示例在单独的文件中定义了该函数并将其导入到两个配置中。 wrap-with-provider.js 不是一个特殊的文件名,它只是一个函数的持有者。

A wrapRootElement 函数接收 element 作为类似于 children 道具的道具。我们的函数创建了一个商店实例和 returns 一个 Provider,该商店的 element 作为其 child。我们正在这个函数中创建商店,因此如果您当前的 redux 文件正在导出一个已创建的 store 作为常量,您将需要导出一个创建商店的可调用函数。你可以看到他们的例子here.

wrap-with-provider.js

import React from "react"
import { Provider } from "react-redux"

import createStore from "./src/state/createStore"

// eslint-disable-next-line react/display-name,react/prop-types
export default ({ element }) => {
  // Instantiating store in `wrapRootElement` handler ensures:
  //  - there is fresh store for each SSR page
  //  - it will be called only once in browser, when React mounts
  const store = createStore()
  return <Provider store={store}>{element}</Provider>
}

同样,此文件本身不会操纵 Gatsby 行为。为此,我们需要导出它的值并将其分配给配置文件中的特殊变量。这些文件如下:

gatsby-browser.js

import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider

gatsby-ssr.js

import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider

两者内容相同。我们所做的只是导入我们在 wrap-with-provider.js 中创建的函数并将其分配给控制行为的特殊命名变量 wrapRootElement

已经发布的答案和评论中发布的 Freecodecamp link 都是非常有用的资源,但是对于我的特定用例,我发现查看 redux 上的 Gatsby 存储库最有帮助”:https://github.com/gatsbyjs/gatsby/tree/master/examples/using-redux

此外,我最终意识到 sessionStorage 更适合我的用例,因为我试图在页面刷新之外存储数据并且我没有使用 Redux 提供的其他功能。您可以在此处阅读有关 localStorage 的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage Redux 和本地存储的区别在这里:

此外,如果您使用的是 Redux,我强烈推荐 redux-devtools 扩展用于调试,您可以在此处安装软件包:https://www.npmjs.com/package/@redux-devtools/extension 并在此处安装浏览器扩展: https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en