从 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 挂钩 useSelector
和 useDispatch
或 connect
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.
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 行为。为此,我们需要导出它的值并将其分配给配置文件中的特殊变量。这些文件如下:
import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider
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
我的应用是这样的:
盖茨比项目
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 挂钩 useSelector
和 useDispatch
或 connect
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.
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 行为。为此,我们需要导出它的值并将其分配给配置文件中的特殊变量。这些文件如下:
import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider
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