gatsby
Cover Photo by Anas Alshanti on Unsplash
封面图片由Anas Alshanti拍摄于Unsplash
问题” (The “problem”)
When using the static site generator Gatsby you don’t have a base “App” component to play with. That said, there’s no component that wraps around your whole application where you can put your state that needs to be kept between routes/pages. Gatsby.js automatically (or automagically?) creates routes to pages you put in your page folder of your installation. Or, you create pages programmatically from your gatsby-node.js file.
使用静态网站生成器Gatsby时,您没有可使用的基本“应用”组件。 也就是说,没有组件可以包裹整个应用程序,您可以在其中放置需要保存在路由/页面之间的状态。 Gatsby.js自动(或自动地?)创建到放置在安装页面文件夹中的页面的路由。 或者,您可以通过gatsby-node.js文件以编程方式创建页面。
This will get us in trouble if we need, for example, a menu that should be visible and available for interaction on all our page routes. In my case, I had a mail form menu that could be shown or hidden in the right lower corner of my application. This component has a local state that will decide if the component is being shown or not. The below image shows the menu closed and opened.
例如,如果我们需要一个应该可见的菜单,并且可以在我们所有的页面路由上进行交互,那么这将给我们带来麻烦。 就我而言,我有一个邮件表单菜单,可以在应用程序的右下角显示或隐藏它。 该组件具有本地状态,该状态将决定是否显示该组件。 下图显示了关闭和打开的菜单。
So… this is our problem. How can we tackle it? There’s a number of ways to deal with this but one way, and the approach I took, is described below.
所以……这是我们的问题。 我们该如何解决? 有很多方法可以解决这个问题,但是下面将介绍一种方法以及我采用的方法。
解决方案 (The Solution)
I’ll go straight to the point. Gatsby has a file that’s named gatsby-browser.js. We can use this file to make components wrap around our complete App and pages!
我将直奔主题。 Gatsby的文件名为gatsby-browser.js。 我们可以使用此文件使组件环绕我们完整的应用程序和页面!
This is great!
这很棒!
This file lets us use the Gatsby Browser API. This API contains several useful functions but there’s one in particular that will fit our needs. It’s called wrapPageElement. Check out the code below. This is the actual code I used for my client’s app.
该文件使我们可以使用Gatsby Browser API。 该API包含几个有用的功能,但其中一个特别适合我们的需求。 它称为wrapPageElement。 查看下面的代码。 这是我用于客户应用程序的实际代码。
// gatsby-browser.js
// Import the component at the top of the file
import MailWidgetWrapper from './src/components/MailWidgetWrapper';
export const wrapPageElement = ({ element, props }) => (
<MailWidgetWrapper {...props}>{element}</MailWidgetWrapper>
);
Here, I’ve created a wrapper component that will be available on all the routes and pages in Gatsby. That’s Awesome! And just what we need. The wrapper component looks like this:
在这里,我创建了一个包装器组件,该组件将在盖茨比的所有路线和页面上使用。 棒极了! 而正是我们需要的。 包装器组件如下所示:
// MailWidgetWrapper.js
import React from 'react';
import MailWidget from './MailWidget';
const MailWidgetWrapper = ({ children }) => (
<>
{children}
<MailWidget />
</>
);
export default MailWidgetWrapper;
This is a really simple React Component who’s only function is to wrap our app and provide it with the MailWidget component. But how does wrapPageElement work?
这是一个非常简单的React Component,它的唯一功能是包装我们的应用程序并为其提供MailWidget组件。 但是wrapPageElement如何工作?
wrapPageElement (wrapPageElement)
First, I also highly recommend using gatsbyjs.org as much as you can for finding answers to anything regarding Gatsby. The site is excellent and full of really good and thorough explanations of most problems you will encounter.
首先,我也强烈建议您尽可能多地使用gatsbyjs.org,以找到有关盖茨比的所有问题的答案。 该站点非常出色,并为您将遇到的大多数问题提供了非常好的详尽的解释。
In our case, if you look at the code above, we have two parameters that get created for us in the wrapPageElement
callback function: element and props.
在我们的例子中,如果您看上面的代码,则在wrapPageElement
回调函数中为我们创建了两个参数: element和props。
You should be familiar with props if you use React so they need no further introduction. In this case, the props are used by the page we’re currently on. We don’t need to use any of these props, as we only need to use the children (automatically created by React) prop.
如果您使用React,那么您应该熟悉道具,因此它们不需要进一步介绍。 在这种情况下,道具将被当前页面所使用。 我们不需要使用任何这些道具,因为我们只需要使用子元素(由React自动创建)道具即可。
The MailWidgetWrapper
just renders the children and the MailWidget
. The children are the page we’re sending into the MailWidgetWrapper
component from the gatsby-browser.js file, as shown below. The actual page lives in the element parameter and that’s the one we’re sending in with the expression {element}
.
MailWidgetWrapper
仅呈现子项和MailWidget
。 子级是我们从gatsby-browser.js文件发送到MailWidgetWrapper
组件的页面 ,如下所示。 实际页面位于element参数中,这就是我们要使用表达式{element}
。
<MailWidgetWrapper {…props}>{element}</MailWidgetWrapper>
So in short, the parameters we get from wrapPageElement
can be summarized:
简而言之,我们可以总结从wrapPageElement
获得的参数:
The props parameter are the props from the actual page we’re on. And the element parameter is the actual page we’re on
props参数是来自我们实际页面上的props。 而element参数是我们所在的实际页面
MailWidget组件 (The MailWidget Component)
My actual MailWidget
component is quite large and has a lot of code that’s not relevant here. That’s why I'm just showing you a simple scaffolded example version of a MailWidget
component below. This component is not actually relevant for the task of explaining the wrapPageElement
function.
我实际的MailWidget
组件很大,并且有很多与此处无关的代码。 这就是为什么我MailWidget
您展示MailWidget
组件的简单脚手架示例版本。 该组件实际上与解释wrapPageElement
函数的任务wrapPageElement
。
The component can virtually be anything you like and has nothing to do with the implementation above. In my case it’s a MailWidget
. It’s all up to you and what stateful component/s you need to be available on all your page routes.
该组件实际上可以是任何您喜欢的组件,并且与上述实现无关。 就我而言,这是一个MailWidget
。 这完全取决于您,以及您需要在所有页面路由中使用哪些状态组件。
// MailWidget.js
import React, { useState } from 'react';
const MailWidget = () => {
const [isVisible, setIsVisible] = useState(false);
const toggleVisible = () => {
setIsVisible(!isVisible);
};
return (
<div className={isVisible ? 'visible' : ''}>
<button type="button" onClick={toggleVisible}>
Hide/Show MailWidget
</button>
<h1>Hello, I'm your mailwidget</h1>
</div>
);
};
export default MailWidget;
By the way, I’m all in on Hooks. I love Hooks and will use them in everything I do in React! That’s why I created my state with the useState
hook in this one. The component above just uses a local state to decide if it should show itself or not.
顺便说一句,我全力以赴。 我喜欢Hook,并将在我在React中所做的一切中使用它们! 这就是为什么我在此代码中使用useState
钩子创建状态的原因。 上面的组件仅使用本地状态来决定是否应显示自己。
结论 (Conclusion)
There you have it! Hopefully, you’ve learned that it’s not difficult to have a component keeping its state between pages in Gatsby. And we all love Gatsby.js don’t we? 😏
你有它! 希望您已经了解到,让组件在Gatsby中的页面之间保持其状态并不难。 而且我们都喜欢Gatsby.js,不是吗? 😏
Also, thank you for reading this post. I’m a Developer from Sweden that loves to teach and code. I also create courses on React and Gatsby online. You can find me on Udemy. Just search for Thomas Weibenfalk or hook me up on Twitter @weibenfalkI also have a Youtube channel were I teach free stuff, check it out here.
另外,感谢您阅读这篇文章。 我是一位来自瑞典的开发人员,喜欢教书和编码。 我还在线创建关于React和Gatsby的课程。 您可以在Udemy上找到我。 只是搜索Thomas Weibenfalk或在Twitter @weibenfalk上吸引我,如果我教免费内容,我也有一个YouTube频道,请在此处查看 。
翻译自: https://www.freecodecamp.org/news/keeping-state-between-pages-with-local-state-in-gatsby-js/
gatsby