Loving Tina? us on GitHub0.0k
使用Tina + Gatsby编辑Markdown的3种方式
January 9, 2020
By Thomas Weibenfalk

通过实时内容编辑为您的静态网站增添动力! 🚀

在这篇文章中,我将探讨Tina提供的三种不同方法来编辑您Gatsby网站上的Markdown。您将学习如何使用Page Queries和Static Queries来设置Tina。

本文不会涵盖在Gatsby中使用Tina的基础知识。请参考文档了解如何最初设置Tina与Gatsby。

Page Queries和Static Queries是什么?

在深入了解如何使用Tina编辑Markdown之前,我们必须了解Gatsby如何使用GraphQL处理数据查询。您可以在Gatsby中几乎从任何地方获取数据。在我们的例子中,我们使用Markdown。当您构建网站时,Gatsby会为所有数据创建一个GraphQL模式。然后,您可以在React组件中使用GraphQL来查询您的数据源。

Gatsby允许您通过两种方式查询数据:Page Queries和Static Queries。 自从发布React Hooks API和Gatsby中的useStaticQuery hook以来,查询数据变得非常容易。不过,有些情况下您不能使用Static Query。首先,让我们探讨一下它们的区别。

两者的主要区别是:

  • Page Queries可以接受GraphQL变量。Static Queries不能。
  • Page Queries只能添加到页面组件中。Static Queries可以在所有组件中使用。

那么,为什么不能在Static Query中使用GraphQL变量呢?原因是Static Query无法像Page Query那样访问页面上下文。结果是Static Query无法访问在页面上下文中定义的变量。您可以在gatsby-node.js文件中的createPage函数中定义页面上下文。在这里,您可以为页面提供不同的变量,这些变量将在构建时注入到页面中。

我尽可能多地使用Static Queries,因为我喜欢hooks API及其带来的组合可能性。例如,您可以创建自定义hooks并在多个组件中重用它们。

假设您有一个GraphQL查询,它获取您想在多个页面上使用的元数据。创建一个包含useStaticQuery Gatsby hook的自定义React hook。然后,您可以在任何需要的地方使用您的自定义hook,并始终轻松地将数据获取到您的组件中。当您需要在组件中使用变量时,您必须使用Page Query。Page Queries不能与hooks API一起使用,必须是唯一的并附加到特定的页面组件。

Static Queries的另一个好处是,您可以在需要数据的组件中获取数据。这可以防止*prop drilling*,并且您的数据与使用它的组件更加紧密耦合。

React概述

为了获取数据,我们可以使用Gatsby的查询选项。为了构建我们的组件,React还提供了一些选项。您可以将组件创建为类组件或函数组件。在React Hooks API之前,您必须使用类组件来在组件中拥有状态。现在有了hooks,您可以在函数组件中做到这一点。🥰

使用Tina编辑Markdown的三种方式

鉴于在Gatsby中创建组件和获取数据的所有选项,我们必须为项目选择最合适的方法。Tina可以与所有这些选项一起工作,提供**三种不同的方法**来编辑Gatsby中的Markdown,如下所述。

  • remarkForm - 一个高阶组件,用于从Gatsby中的Page Query获取数据时使用。此组件可用于函数和类组件。请注意这里的细微差别!与渲染props组件的唯一命名区别是小写的“r”。
  • useLocalRemarkForm - 一个React Hook,用于从Static或Page Query获取数据的函数组件。如果组件获取的是静态数据,将调用Gatsby的useStaticQuery hook。
  • RemarkForm - 一个渲染Props组件,您可以在类组件中使用,从Static或Page Query获取数据。静态数据将通过Gatsby的StaticQuery渲染Props组件获取。

remarkForm - 如何使用以及为什么它不能与Static Queries一起使用

首先,让我们深入了解如何将TinaCMS与Page Query连接起来。 TinaCMS中的remarkForm组件是一个高阶组件,简称HOC。这意味着它是一个接受另一个组件并返回一个具有附加功能的新组件的函数。

如果您不熟悉HOC,我建议您在React官方文档中阅读相关内容。它们在React世界中被认为是“高级用法”。

remarkForm组件需要另一个组件作为参数,并用于Page Queries。Page Query将数据作为prop注入到组件中,我们从这个prop中访问数据。使用useStaticQuery hook,数据在组件内部的一个变量中收集,这意味着如果您在Gatsby中使用useStaticQuery hook,您将没有组件来提供给remarkForm HOC。遗憾!😞 这就是为什么您只能将remarkForm组件与Page Queries一起使用。

那么如何在Gatsby中使用这个组件与Page Query呢?首先,查看下面的虚构星球大战组件。它将展示连接所有内容所需的三个步骤:

// 1. 导入`remarkForm` HOC
import { remarkForm } from 'gatsby-tinacms-remark'
const StarWarsMovie = ({ data: { markdownRemark } }) => {
return <h1>{markdownRemark.frontmatter.title}</h1>
}
// 2. 使用`remarkForm`包装您的组件
export default remarkForm(StarWarsMovie)
// 3. 将所需的...TinaRemark片段添加到您的Page Query中
export const pageQuery = graphql`
query StarWarsMovieById($id: String!) {
markdownRemark(fields: { id: { eq: $id } }) {
id
html
frontmatter {
title
releaseDate
crawl
}
...TinaRemark
}
}
`

上面的代码是一个显示星球大战电影信息的组件。目前,它只显示一个标题,但它也可以显示发布日期和电影开头的爬行文本。但那是另一个遥远星系中的故事... ⭐

这个例子中的第一步是从Gatsby插件gatsby-tinacms-remark中导入remarkForm hook。这是使TinaCMS与Markdown文件一起工作的插件。

无需对组件内部的代码进行任何添加。它可以是任何组件——函数或类——按照您想要的方式构建。您唯一需要对组件本身做的就是在导出时使用remarkForm HOC包装您的组件。

在您准备好之前,您还需要做一件事,就是在查询中添加GraphQL片段...TinaRemark。这是TinaCMS识别您的数据并在TinaCMS侧边栏中创建所需编辑器字段所必需的。之后,您只需启动开发服务器以显示网站和Tina侧边栏。

够简单吧?只需三个小步骤,您就可以在网站上编辑内容的漂亮侧边栏。🤟

但如果您想使用Static Query而不是Page Query怎么办?

useLocalRemarkForm来救援!

我们已经了解到remarkForm HOC无法在Static Queries上工作。因此,我们必须找到另一种解决方案来使用TinaCMS的Static Queries。

好消息!

remarkForm组件本质上是useLocalRemarkForm hook的“包装器”。👀 它接受一个组件作为参数,使用Page Query数据调用useLocalRemarkForm,并返回一个带有查询数据和TinaCMS连接的新组件。

我们可以直接使用useLocalRemarkForm hook,而不使用remarkForm HOC。这在Static Queries中或我们只是喜欢使用hooks时非常有用!

看看下面的代码示例,了解useLocalRemarkForm的工作原理。

// 1. 导入useLocalRemarkForm hook
import React from ‘react’;
import { useLocalRemarkForm } from ‘gatsby-tinacms-remark’;
import { useStaticQuery } from ‘gatsby’;
const StarWarsMovie = () => {
// 2. 将所需的TinaCMS片段添加到GraphQL查询中
const data = useStaticQuery(graphql`
query StarWarsMovieById {
markdownRemark(fields: { id: { eq: "sw-01" } }) {
id
html
frontmatter {
title
releaseDate
crawl
}
...TinaRemark
}
}
`);
// 3. 调用useLocalRemarkForm hook并传入数据
const [markdownRemark] = useLocalRemarkForm(data.markdownRemark);
return <h1>{markdownRemark.frontmatter.title}</h1>
}
export default StarWarsMovie;

这只是一个示例组件,说明useLocalRemarkForm的工作原理。在现实世界中,使用Static Query不是一个最佳解决方案。因为,正如您所见,您无法在useStaticQuery hook中使用变量来使其动态化。您必须硬编码电影ID。因此,此查询仅适用于特定电影,这不好。

让我们分解一下这里发生的事情:

  1. 我们导入useLocalRemarkForm自定义hook,以便在组件中使用它。
  2. 与之前一样,GraphQL查询中需要...TinaRemark片段。因此,我们在那里添加它。
  3. 当我们从Gatsby的useStaticQuery hook中获取数据后,我们可以使用该数据调用TinaCMS的useLocalRemarkForm hook。此hook将返回一个包含两个元素的数组。第一个元素实际上是我们调用hook时的数据。它具有相同的形状,并准备好在我们的组件中使用。第二个元素是Tina表单的引用。我们不需要那个,所以我们不将其解构出来,就像我们对markdownRemark所做的那样。

如果您对这一行感到疑惑:

const [markdownRemark] = useLocalRemarkForm(heroData.markdownRemark)

这是ES6解构的一个例子。由于我们得到一个包含两个元素的数组,我解构出第一个元素(即我们的数据)并将其命名为markdownRemark。您可以随意命名。

RemarkForm - 渲染Props组件

您不能在类组件上使用React Hooks。这就是为什么Tina提供了一个使用渲染Props模式的RemarkForm组件。

此组件适用于Page和Static Queries。我将在下面展示如何与Page Query一起使用。

请看下面的示例:

// 1. 导入RemarkForm渲染Props组件
import { RemarkForm } from '@tinacms/gatsby-tinacms-remark'
class StarWarsMovie extends React.Component {
render() {
/*
** 2. 返回RemarkForm,传入markdownRemark
** 到remark prop并传入您想要渲染的内容到render prop
*/
return (
<RemarkForm
remark={this.props.data.markdownRemark}
render={({ markdownRemark }) => {
return <h1>{markdownRemark.frontmatter.title}</h1>
}}
/>
)
}
}
export default StarWarsMovie
// 3. 将所需的...TinaRemark片段添加到您的Page Query中
export const pageQuery = graphql`
query StarWarsMovieById($id: String!) {
markdownRemark(fields: { id: { eq: $id } }) {
id
html
frontmatter {
title
releaseDate
crawl
}
...TinaRemark
}
}
`

好的,再次让我们看看这里发生了什么:

  1. 我们导入RemarkForm组件以便在代码中使用。
  2. 在我们的返回语句中,我们返回RemarkForm组件并传入其预定义和必需的props。remark prop提供RemarkForm从Page Query获取的Markdown数据。render prop通过函数或渲染prop获取我们想要渲染的JSX。RemarkForm将连接Tina以编辑数据,然后渲染在render prop函数中指定的内容。
  3. 与之前一样,我们必须将...TinaRemark片段添加到Page Query中。

下一步

就是这样!在Gatsby中使用Tina编辑Markdown文件的三种方式。🎉

在这篇文章中,我们学习了如何在Gatsby中设置Tina与Static Queries和Page Queries。我们还根据您的React组件类型学习了三种不同的方式来使用Tina编辑Markdown。

这只是让您入门的基础。如果您喜欢Tina并想了解更多,您应该查看官方文档。那里有很多内容可以阅读,还有一些有趣的用例。

例如,您可以学习如何应用内联编辑,以及如何在Tina侧边栏中自定义表单字段

Tina是React生态系统和静态网站生成器如Gatsby的一个很好的补充。它为您的网站提供了一种愉快且简单的方式来编辑和与您的内容互动。 我很高兴看到TinaCMS会有多大,以及它在发展过程中能做些什么!

更多阅读和学习

观看我的Tina & Gatsby教程。也可以在Twitter上找到我——@weibenfalkYoutube,或在我的网站上。