在页面入口处仅显示一次覆盖(不是路线更改)。如何?
Show overlay only once on page entrance (not route change). HowTo?
所以我尝试在我的 gatsby 网站上覆盖大约一秒钟,让它在后面加载正确的断点。我怎样才能做到这一点?
所以我设置了一个Interval和一些State来加载Overlay并让它在一个间隔后消失。但是每次页面重新加载覆盖后问题再次出现。我没有像 redux 这样的状态管理,我需要 Overlay 仅在每次刷新或从外部 links 进入后出现,而不是单击内部 links.
我已经尝试 useEffect
仅在安装上进行渲染,但这并不能解决问题,因为内部 link 更改将触发重新安装
我发现我可以使用浏览器 API onInitialClientRender。但是我不明白如何在 gatsby-browser.js 之外访问其中生成的值。总的来说,我在理解如何使用这些 API 时遇到问题。
customHooks.js
export function useInterval(callback, delay) {
const savedCallback = useRef()
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback
}, [callback])
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current()
}
if (delay !== null) {
let id = setInterval(tick, delay)
return () => clearInterval(id)
}
}, [delay])
}
Layout.js
let [loadingIndicator, setLoadingIndicator] = useState(true)
const delay = 500
useInterval(() => {
setLoadingIndicator(false)
}, delay)
因此,预期的结果将是一种方式,告诉初始客户端渲染设置一个状态,该状态告诉要渲染的叠加层,并且在这个渲染之后状态应该改变以禁用叠加层的渲染。
解法:
使用 gatsby 的能力改变静态 index.html 文件。 [在 Gatsby 中自定义 Index.html][1]
将自定义 div 添加到生成的 html.js
html.js:
<div
key={`loader`}
id="___loader"
style={{
alignItems: "center",
backgroundColor: "#F2F2F2",
display: "flex",
justifyContent: "center",
position: "absolute",
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: 1,
}}
>
<LoaderSVG width="50%" />
</div>
在盖茨比中-browser.js:
gatsby-browser.js:
export const onInitialClientRender = () => {
document.getElementById("___gatsby").style.display = "block"
setTimeout(function() {
document.getElementById("___loader").style.display = "none"
}, 200)
}
下一步是检查是否所有数据都已加载并添加动态值而不是超时。
我做了这样的事情。
我从 .cache 目录复制了默认 html 并粘贴到 src 目录。
我使用了以下命令:
cp .cache/default-html.js src/html.js
在 html.js 文件中,我注意到以下代码:
import React from "react"
import PropTypes from "prop-types"
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
我放了 SVG 加载器,它是一个图像和几行 CSS:
所以完整的代码是这样的:
import React from "react"
import PropTypes from "prop-types"
import LoaderSVG from './img/loader.svg'
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`loader`}
id="___loader"
style={{
alignItems: "center",
backgroundColor: "#F2F2F2",
display: "flex",
justifyContent: "center",
position: "absolute",
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: 1,
}}
>
<img src={LoaderSVG} alt="" width="150"/>
</div>
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
<script
dangerouslySetInnerHTML={{
__html: `
setTimeout(function() {
document.getElementById("___loader").style.display = "none"
}, 200)
`,
}}
/>
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
然后重启 Gatsby 就可以了。
所以我尝试在我的 gatsby 网站上覆盖大约一秒钟,让它在后面加载正确的断点。我怎样才能做到这一点?
所以我设置了一个Interval和一些State来加载Overlay并让它在一个间隔后消失。但是每次页面重新加载覆盖后问题再次出现。我没有像 redux 这样的状态管理,我需要 Overlay 仅在每次刷新或从外部 links 进入后出现,而不是单击内部 links.
我已经尝试 useEffect
仅在安装上进行渲染,但这并不能解决问题,因为内部 link 更改将触发重新安装
我发现我可以使用浏览器 API onInitialClientRender。但是我不明白如何在 gatsby-browser.js 之外访问其中生成的值。总的来说,我在理解如何使用这些 API 时遇到问题。
customHooks.js
export function useInterval(callback, delay) {
const savedCallback = useRef()
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback
}, [callback])
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current()
}
if (delay !== null) {
let id = setInterval(tick, delay)
return () => clearInterval(id)
}
}, [delay])
}
Layout.js
let [loadingIndicator, setLoadingIndicator] = useState(true)
const delay = 500
useInterval(() => {
setLoadingIndicator(false)
}, delay)
因此,预期的结果将是一种方式,告诉初始客户端渲染设置一个状态,该状态告诉要渲染的叠加层,并且在这个渲染之后状态应该改变以禁用叠加层的渲染。
解法:
使用 gatsby 的能力改变静态 index.html 文件。 [在 Gatsby 中自定义 Index.html][1]
将自定义 div 添加到生成的 html.js
html.js:
<div
key={`loader`}
id="___loader"
style={{
alignItems: "center",
backgroundColor: "#F2F2F2",
display: "flex",
justifyContent: "center",
position: "absolute",
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: 1,
}}
>
<LoaderSVG width="50%" />
</div>
在盖茨比中-browser.js:
gatsby-browser.js:
export const onInitialClientRender = () => {
document.getElementById("___gatsby").style.display = "block"
setTimeout(function() {
document.getElementById("___loader").style.display = "none"
}, 200)
}
下一步是检查是否所有数据都已加载并添加动态值而不是超时。
我做了这样的事情。
我从 .cache 目录复制了默认 html 并粘贴到 src 目录。
我使用了以下命令:
cp .cache/default-html.js src/html.js
在 html.js 文件中,我注意到以下代码:
import React from "react"
import PropTypes from "prop-types"
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
我放了 SVG 加载器,它是一个图像和几行 CSS:
所以完整的代码是这样的:
import React from "react"
import PropTypes from "prop-types"
import LoaderSVG from './img/loader.svg'
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`loader`}
id="___loader"
style={{
alignItems: "center",
backgroundColor: "#F2F2F2",
display: "flex",
justifyContent: "center",
position: "absolute",
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: 1,
}}
>
<img src={LoaderSVG} alt="" width="150"/>
</div>
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
<script
dangerouslySetInnerHTML={{
__html: `
setTimeout(function() {
document.getElementById("___loader").style.display = "none"
}, 200)
`,
}}
/>
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
然后重启 Gatsby 就可以了。