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

问题描述 投票:0回答:2

我的应用程序是这样的:

盖茨比项目

index.tsx - 应用程序的入口点 - 我调用

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

HomePage.js 使用

mapStateToProps
并使用
connect(mapStateToProps)(HomePage)

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

HomePage

在我的主页上,我有指向

ActivityPage
的链接。一旦我点击此页面并登陆那里 - 问题就开始了。

ActivityPage 使用多个子组件来完成任务。如何从 ActivityPage 访问读/写?

我无法

useDispatch
在商店中写入甚至读取。我可以在我的 ReactDev 工具上看到该商店,但在尝试读/写时,我收到 11 个错误,大部分是沿着我需要用
<Provider>

包装组件的思路

我在 Stack Overflow 上阅读了不同的解决方案,这表明我需要拥有

mapStateToProps
并在我需要访问商店的任何组件上使用
connect

这不起作用,因为我特别希望从“新页面”访问商店。我需要为我的子页面创建另一家商店吗?请帮助。 :

reactjs redux react-redux gatsby
2个回答
7
投票

您的组件必须位于 redux

Provider
组件内部才能使用 redux 钩子
useSelector
useDispatch
connect
HOC。

在典型的 React 应用程序中,您会将

Provider
放在
App
组件中,该组件是所有内容的父组件。然而,Gatsby 使用不同的设置,其中每个页面完全独立,因此没有共享的父级,我们可以在其中放置
Provider

Gatsby 所做的 是一个 API,用于通过在配置文件中定义函数来覆盖自定义行为。您可以将一堆文件放置在应用程序的根目录中、与

package.json
相同的文件夹中以及
src
之外。我们在这里使用的两个是
gatsby-browser.js
,它控制客户端,以及
gatsby-ssr.js
,它控制通过服务器端渲染创建静态 HTML 页面。这两个文件都支持一个名为
wrapRootElement
的功能。

我们使用

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

A

wrapRootElement
函数接收
element
作为道具,类似于
children
道具。我们的函数创建一个商店实例并返回一个
Provider
,该商店以
element
作为其子级。我们正在这个函数中创建存储,因此如果您当前的 redux 文件将创建的
store
导出为常量,您将需要导出一个可调用函数来创建存储。您可以在此处查看他们的示例。

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


0
投票

已经发布的答案和评论中发布的 Freecodecamp 链接都是非常有用的资源,但是对于我的特定用例,我发现查看 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 而不是 session 存储

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

© www.soinside.com 2019 - 2024. All rights reserved.