为什么每次我点击其中一个链接时,我的 TOC 组件都会在其链接中添加 `{"-" + 1}`?
Why does my TOC component add `{"-" + 1}` to its links every time I click on one of them?
我在 this tutorial.
之后在我的网站上实施了一个 table-of-contents 组件
有效,但每次我点击其中一个目录 link 时,目录中的所有 link(包括点击的)都会附加一个 {"-" + 1}
.因此,如果我单击 link,所有这些 link 都会从 #first-heading
、#second-heading
等变为 #first-heading-1
、#second-heading-1
等。如果我再次单击其中一个 link,它们都会得到 #first-heading-2
、#second-heading-2
等,依此类推。这种行为当然是有问题的,因为它破坏了 links.
这是什么原因造成的?我该如何解决?
我注意到教程使用了 remark-slug
plugin for the headings, while I use the gatsby-autolink-headers
插件。这可能是问题的根源吗?我无法使用前者进行测试,因为我在尝试安装它时遇到错误。
编辑:这两个插件我都试过了。同样的问题。
TableOfContents.js
import React from "react"
import Slugger from "github-slugger"
import { Link } from "gatsby"
const slugger = new Slugger()
export default ({ headings }) => (
<div className="table-of-contents">
<h3>On this page</h3>
<ol>
{headings
.filter(heading => heading.depth !== 1)
.map(heading => (
<li key={heading.value}>
<Link
to={"#" + slugger.slug(heading.value)}
>
{heading.value}
</Link>
</li>
))}
</ol>
</div>
)
post-template.js
import * as React from "react"
import { graphql } from "gatsby"
import { MDXRenderer } from "gatsby-plugin-mdx"
import Layout from "../components/layout.js"
import Seo from "../components/seo.js"
const PostTemplate = ({ data, location }) => {
let post = data.mdx
return (
<Layout location={location}>
<Seo
title={post.frontmatter.title}
description={post.frontmatter.lead}
date={post.frontmatter.computerDate}
/>
<article className="article">
<h1 itemprop="headline">{post.frontmatter.title}</h1>
<p
className="lead"
itemprop="introduction"
>
{post.frontmatter.lead}
</p>
<MDXRenderer headings={post.headings}>
{post.body}
</MDXRenderer>
</article>
</Layout>
)
}
export default PostTemplate
export const pageQuery = graphql`
query PostBySlug($id: String!) {
site {
siteMetadata {
title
}
}
mdx(id: {eq: $id}) {
id
excerpt(pruneLength: 160)
body
frontmatter {
title
computerDate: date(formatString: "YYYY-MM-DD")
humanDate: date(formatString: "DD MMMM YYYY")
lead
}
headings {
depth
value
}
}
}
`
index.mdx
---
/* frontmatter */
---
<!-- component imported as shortcode in `layout.js` -->
<TableOfContents headings={props.headings} />
layout.js
(摘录)
import TableOfContents from "./article-components/TableOfContents"
const shortcodes = {
TableOfContents
}
export default function Layout({ children }) {
return (
<div className="layout-wrapper">
<Header />
<main>
<MDXProvider components={shortcodes}>
{children}
</MDXProvider>
</main>
</div>
)
}
因为slugger
。在他们的文档中:
slugger.slug('foo')
// returns 'foo'
slugger.slug('foo')
// returns 'foo-1'
slugger.slug('bar')
// returns 'bar'
slugger.slug('foo')
// returns 'foo-2'
因为它确保 link 是唯一的(就像 GitHub 一样),所以它附加了 -1
、-2
等
只要你使用你的gatsby-autolink-headers
插件就可以摆脱slugger
的实现。如果需要,您可以使用正常的 link 值 (heading.value
)、slug
字段(如果提供),或使用自定义函数对其进行清理,例如:
function slugify (text) {
return text
.toString()
.toLowerCase()
.normalize(`NFD`)
.trim()
.replace(/\s+/g, `-`)
.replace(/[^\w-]+/g, ``)
.replace(/--+/g, `-`);
};
<Link to={"#" + slugify(heading.value)}>
我在 this tutorial.
之后在我的网站上实施了一个 table-of-contents 组件有效,但每次我点击其中一个目录 link 时,目录中的所有 link(包括点击的)都会附加一个 {"-" + 1}
.因此,如果我单击 link,所有这些 link 都会从 #first-heading
、#second-heading
等变为 #first-heading-1
、#second-heading-1
等。如果我再次单击其中一个 link,它们都会得到 #first-heading-2
、#second-heading-2
等,依此类推。这种行为当然是有问题的,因为它破坏了 links.
这是什么原因造成的?我该如何解决?
我注意到教程使用了 remark-slug
plugin for the headings, while I use the gatsby-autolink-headers
插件。这可能是问题的根源吗?我无法使用前者进行测试,因为我在尝试安装它时遇到错误。
编辑:这两个插件我都试过了。同样的问题。
TableOfContents.js
import React from "react"
import Slugger from "github-slugger"
import { Link } from "gatsby"
const slugger = new Slugger()
export default ({ headings }) => (
<div className="table-of-contents">
<h3>On this page</h3>
<ol>
{headings
.filter(heading => heading.depth !== 1)
.map(heading => (
<li key={heading.value}>
<Link
to={"#" + slugger.slug(heading.value)}
>
{heading.value}
</Link>
</li>
))}
</ol>
</div>
)
post-template.js
import * as React from "react"
import { graphql } from "gatsby"
import { MDXRenderer } from "gatsby-plugin-mdx"
import Layout from "../components/layout.js"
import Seo from "../components/seo.js"
const PostTemplate = ({ data, location }) => {
let post = data.mdx
return (
<Layout location={location}>
<Seo
title={post.frontmatter.title}
description={post.frontmatter.lead}
date={post.frontmatter.computerDate}
/>
<article className="article">
<h1 itemprop="headline">{post.frontmatter.title}</h1>
<p
className="lead"
itemprop="introduction"
>
{post.frontmatter.lead}
</p>
<MDXRenderer headings={post.headings}>
{post.body}
</MDXRenderer>
</article>
</Layout>
)
}
export default PostTemplate
export const pageQuery = graphql`
query PostBySlug($id: String!) {
site {
siteMetadata {
title
}
}
mdx(id: {eq: $id}) {
id
excerpt(pruneLength: 160)
body
frontmatter {
title
computerDate: date(formatString: "YYYY-MM-DD")
humanDate: date(formatString: "DD MMMM YYYY")
lead
}
headings {
depth
value
}
}
}
`
index.mdx
---
/* frontmatter */
---
<!-- component imported as shortcode in `layout.js` -->
<TableOfContents headings={props.headings} />
layout.js
(摘录)
import TableOfContents from "./article-components/TableOfContents"
const shortcodes = {
TableOfContents
}
export default function Layout({ children }) {
return (
<div className="layout-wrapper">
<Header />
<main>
<MDXProvider components={shortcodes}>
{children}
</MDXProvider>
</main>
</div>
)
}
因为slugger
。在他们的文档中:
slugger.slug('foo') // returns 'foo' slugger.slug('foo') // returns 'foo-1' slugger.slug('bar') // returns 'bar' slugger.slug('foo') // returns 'foo-2'
因为它确保 link 是唯一的(就像 GitHub 一样),所以它附加了 -1
、-2
等
只要你使用你的gatsby-autolink-headers
插件就可以摆脱slugger
的实现。如果需要,您可以使用正常的 link 值 (heading.value
)、slug
字段(如果提供),或使用自定义函数对其进行清理,例如:
function slugify (text) {
return text
.toString()
.toLowerCase()
.normalize(`NFD`)
.trim()
.replace(/\s+/g, `-`)
.replace(/[^\w-]+/g, ``)
.replace(/--+/g, `-`);
};
<Link to={"#" + slugify(heading.value)}>