在 componentDidMount 中初始化脚本——运行每个路由更改
Initialize script in componentDidMount – runs every route change
我正在为我的 React 应用开发导航栏(准确地说是使用 gatsbyjs)。在导航栏中,我有一个选取框,我在 componentDidMount
.
的导航栏组件中对其进行了初始化
它按预期工作,但在每次路由更改时 componentDidMount
将再次 运行,这导致选取框在每次页面更改时加速,使其运行得越来越快。
这是预期的行为吗?如果是这样,我如何确保脚本仅 运行 一次?
navbar.js
import React from 'react';
import { Link } from 'gatsby';
import styles from '../styles/navbar.module.css';
import NewsMarquee from './newsMarquee';
import Marquee3k from 'marquee3000';
const topLevelNav = [
{
href: '/news',
label: <NewsMarquee/>,
extraClass: styles.navLinkNews,
mediaQueryClass: styles.navLinkHiddenSmall,
},
];
export default class Navbar extends React.Component {
componentDidMount() {
Marquee3k.init();
}
render() {
return (
<div>
<header className={styles.navbar} role="banner">
<nav className={styles.nav}>
{topLevelNav.map(({ href, label, extraClass = '', mediaQueryClass = '' }) => (
<Link
key={label}
to={href}
className={`${styles.navLink} ${extraClass} ${mediaQueryClass} ${menuItemsHidden}`}
activeClassName={styles.navLinkActive}
>
{label}
</Link>
))}
</nav>
</header>
</div>
)
}
}
newsMarquee.js
import React from 'react';
import { StaticQuery, graphql } from "gatsby";
import styles from '../styles/newsMarquee.module.css';
export default () => (
<StaticQuery
query={graphql`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC } limit: 10) {
totalCount
edges {
node {
id
frontmatter {
title
date(formatString: "YYYY.MM.DD")
}
fields {
slug
}
}
}
}
}
`}
render={data => (
<div className={`marquee3k ${styles.marquee}`}>
<div>
{data.allMarkdownRemark.edges.map(({ node }) => (
<span className={styles.marqueeItem} key={node.id}>
{node.frontmatter.date} {node.frontmatter.title}
</span>
))}
</div>
</div>
)}
/>
)
因为我使用的是 GatsbyJS,所以我使用了 V1 中的 this plugin,这使得我的布局组件在页面中保持不变。
gatsby-plugin-layout
此插件允许添加位于页面组件之上并在页面更改时持续存在的组件。
这可能有助于:
- 在页面更改之间保持布局,例如动画导航
- 导航页面时存储状态
- 使用 componentDidCatch 自定义错误处理
- 使用 React Context 将额外数据注入页面。
此插件重新实现了 gatsby@1 中布局组件的行为,该行为已在版本 2 中删除。
我正在为我的 React 应用开发导航栏(准确地说是使用 gatsbyjs)。在导航栏中,我有一个选取框,我在 componentDidMount
.
它按预期工作,但在每次路由更改时 componentDidMount
将再次 运行,这导致选取框在每次页面更改时加速,使其运行得越来越快。
这是预期的行为吗?如果是这样,我如何确保脚本仅 运行 一次?
navbar.js
import React from 'react';
import { Link } from 'gatsby';
import styles from '../styles/navbar.module.css';
import NewsMarquee from './newsMarquee';
import Marquee3k from 'marquee3000';
const topLevelNav = [
{
href: '/news',
label: <NewsMarquee/>,
extraClass: styles.navLinkNews,
mediaQueryClass: styles.navLinkHiddenSmall,
},
];
export default class Navbar extends React.Component {
componentDidMount() {
Marquee3k.init();
}
render() {
return (
<div>
<header className={styles.navbar} role="banner">
<nav className={styles.nav}>
{topLevelNav.map(({ href, label, extraClass = '', mediaQueryClass = '' }) => (
<Link
key={label}
to={href}
className={`${styles.navLink} ${extraClass} ${mediaQueryClass} ${menuItemsHidden}`}
activeClassName={styles.navLinkActive}
>
{label}
</Link>
))}
</nav>
</header>
</div>
)
}
}
newsMarquee.js
import React from 'react';
import { StaticQuery, graphql } from "gatsby";
import styles from '../styles/newsMarquee.module.css';
export default () => (
<StaticQuery
query={graphql`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC } limit: 10) {
totalCount
edges {
node {
id
frontmatter {
title
date(formatString: "YYYY.MM.DD")
}
fields {
slug
}
}
}
}
}
`}
render={data => (
<div className={`marquee3k ${styles.marquee}`}>
<div>
{data.allMarkdownRemark.edges.map(({ node }) => (
<span className={styles.marqueeItem} key={node.id}>
{node.frontmatter.date} {node.frontmatter.title}
</span>
))}
</div>
</div>
)}
/>
)
因为我使用的是 GatsbyJS,所以我使用了 V1 中的 this plugin,这使得我的布局组件在页面中保持不变。
gatsby-plugin-layout
此插件允许添加位于页面组件之上并在页面更改时持续存在的组件。
这可能有助于:
- 在页面更改之间保持布局,例如动画导航
- 导航页面时存储状态
- 使用 componentDidCatch 自定义错误处理
- 使用 React Context 将额外数据注入页面。
此插件重新实现了 gatsby@1 中布局组件的行为,该行为已在版本 2 中删除。