学习开始使用React、Strapi和GraphQL

692 阅读7分钟

React、Strapi和GraphQL的入门教程

Strapi是一个用JavaScript编写的无头CMS(内容管理系统),它使用户能够通过一个用户友好的界面轻松地创建API。

在传统的内容管理系统中,网站的前端和后端部分通常被捆绑在一起。

使用无头CMS,这两部分是分开的。因此,我们可以按照我们想要的方式来定制我们的前端,并使用我们喜欢的语言或框架来创建它。

在这篇文章中,我们将看看我们如何使用Strapi CMS和React来创建一个博客网络应用。

先决条件

要继续学习,你需要具备以下条件。

  • 对React和React钩子有一些了解。
  • 对[GraphQL]有一个基本的了解。
  • 在你的电脑上安装[Node.js]。
  • yarn和npm都应该被启用,以便在同一个项目上工作。

主要收获

本教程将帮助你。

  • 与无头CMS一起工作。
  • 在Strapi CMS中使用GraphQL插件。
  • 使用Apollo和React。

创建一个Strapi应用程序

打开你的终端,导航到你要创建项目的目录,并为项目创建一个文件夹,如下图所示。

mkdir react-strapi-blog && cd react-strapi-blog

使用下面的代码来创建Strapi应用程序。

npx create-strapi-app backend

你将得到这些选项。

Installation Type

选择Quickstart ,用推荐的设置安装Strapi。

一旦安装完成,Strapi将自动在http://localhost:1337/admin/auth/register-admin ,启动一个本地开发服务器,为我们提供管理后台。

在这个URL上,将出现以下页面。填写所需的证书以创建一个管理员用户,然后点击Let's Start

Register Admin

如果这不是自动发生的,cd 进入backend 文件夹并运行下面的命令。

npm run develop

然后你将被重定向到http://localhost:1337/admin/ ,这是Strapi管理仪表板。仪表板看起来像这样。

Admin Dashboard

创建内容类型

一个内容类型是一块内容的蓝图。它描述了内容应该有哪些字段和数据类型。

例如,一个博客内容类型可能有一个标题字段、一个正文字段和一个作者字段

要创建一个内容类型,点击左侧边栏的Content-Type Builder 。将出现以下屏幕。

Content Type

COLLECTION TYPES ,点击Create new collection type

New Collection Type

在显示名称下,输入blog ,如上所示,其他字段将自动生成其文本。点击Continue

然后你会看到以下屏幕,你将为你的内容类型选择一个字段。选择Text

Blog Fields

在下一个屏幕(如下图所示),为你的字段添加一个名称,输入Title ,这将代表博客的标题

Text Fields

点击Add another field ,添加其他字段。按照这个过程,添加以下两个字段。

  • 选择字段Rich Text ,并给它命名为Body 。这将存储博客的内容/正文。

  • 选择字段Text ,并给它命名为Author 。这将存储作者的名字。

在你添加完所有的字段后,点击完成

创建新的博客

要创建新的博客,我们以后将从前端获取,点击管理仪表板侧边栏上的Content Manager ,你将看到以下屏幕。

Add Blogs

点击Create new entry 来添加一个博客。输入博客的标题、正文作者。然后点击SavePublish ,这样就可以从前端检索到该博客。

要添加新的博客,请点击顶部的Back 按钮并选择Add new entry 。尽可能多地创建你想要的博客。在本教程中,我已经创建了3个博客。

设置权限

默认情况下,Strapi对内容类型进行保护,使其不能被公众访问。为了从前端访问Strapi中的数据,我们需要更新权限。

在管理仪表板上,点击Settings 。在USERS & PERMISSIONS PLUGIN ,选择Roles ,你会看到下面的屏幕。

Roles

点击Public ,在权限下选择Blog ,并在findfindOne 领域打勾,如下图所示。

Permissions

点击Save 。上述配置将使前台能够检索到单个或多个博客。

安装GraphQL插件

为了在我们的Strapi应用程序中使用GraphQL,我们需要安装该插件。打开正在运行的Strapi应用程序的终端,按Ctrl + C ,停止服务器。

运行下面的命令来安装GraphQL。

yarn strapi install graphql

创建一个React应用程序

现在后端已经全部设置好了,我们现在可以创建前端。要创建React应用程序,在适当的文件夹中运行下面的代码。

npx create-react-app frontend

在React应用程序被成功创建后,我们需要安装以下软件包。

  • apollo-client- 这将帮助我们在React组件中管理和进行查询。
  • graphql- 解析GraphQL查询。
  • react-router-dom- 在Web应用程序中设置路由。

运行下面的代码来安装它们。

npm install @apollo/client graphql react-router-dom

我们将使用TailwindCSS来设计我们的React应用程序。

安装完成后,在src 目录中创建两个新的文件夹,名称为componentspages

components文件夹中,创建一个名为Header.js 的新文件,并粘贴以下代码。

import React from 'react';
import { Link } from 'react-router-dom';

export default function Header() {
  return (
      <Link to={`/`}> 
        <h2 className='text-3xl text-purple-600'>
          Strapi React Blog      
        </h2>
      </Link>
  );
}

在上面的代码中,我们为我们的网络应用程序创建了一个简单的标题,并将其链接到主页上。

创建页面

pages 文件夹中,创建两个新文件,即Homepage.js (它将被用来显示所有博客的列表)和BlogDetails.js (这将被用来显示单个博客的内容)。

打开Homepage.js 文件,粘贴下面的代码。

//Make the necessary imports
import React from 'react';
import { useQuery, gql } from '@apollo/client'
import { Link } from 'react-router-dom'

//GraphQL query to fetch all the blogs from the backend
const BLOGS = gql`
{
    blogs {
      data {
        id
        attributes {
          Title
          Body
          Author
        }
      }
    }
  }
`

export default function Homepage() {

//Execute the query using the useQuery hook and store the return values.
const { loading, error, data } = useQuery(BLOGS)

//Display the following when fetching
if (loading) return <p>Loading...</p>
//Display the following in case an error is encountered
if (error) return <p>Error :(</p>
//log the data to the console
console.log(data)
  return (
      <div>
      {/* Map through the data */}
          {
            data.blogs.data.map(blog => (
                <div key={blog.id} className='mt-2 mb-2 p-4 bg-white rounded-md'>
                    <div className='text-xl'>
                        {blog.attributes.Title}
                    </div>

                    <small>
                        {blog.attributes.Author}
                    </small>

                    {/* Display only the first 150 characters of the body */}
                    <div>
                        {blog.attributes.Body.substring(0,150)}...
                    </div>

                    {/* Link to display the whole blog content */}
                    <Link to={`/blog/${blog.id}`} className='text-purple-600'>Read more...</Link>
                </div>
            ))
          }
      </div>
  );
}

代码解释。

  • gql 是由apollo用来将查询字符串转换成apollo可以理解的格式。

  • 在上面的代码中,我们写了一个查询,从后台获取所有的博客,存储在一个const BLOGS ,然后使用useQuery() 钩子来执行查询。

  • useQuery() 是一个React钩子。它与我们的用户界面共享graphql数据。

  • useQuery() 钩子自动执行我们的查询并将结果存储在一个对象中。这个对象包含loading,error, 和data 属性。

  • 在成功获取数据后,我们使用JavaScriptmap() 方法对其进行映射,并将其显示在用户界面上。

接下来,打开BlogDetails.js 文件并粘贴以下代码。

//Make the necessary imports
import React from 'react';
import { useParams } from 'react-router-dom';
import { useQuery, gql } from '@apollo/client'

//Create the query
const BLOG = gql`
query GetBlog($id: ID!) {
        blog(id: $id) {
          data {
            id
            attributes {
              Title
              Body
              Author
            }
          }
        }
}
`

export default function BlogDetails() {
    //Get the id from the URL
    const { id } = useParams()

    //Pass variables to the query and execute it. Store the results in an object
    const { loading, error, data } = useQuery(BLOG, {
        variables: { id: id }
      })

    //Display messages accordingly
      if (loading) return <p>Loading...</p>
      if (error) return <p>Error :(</p>
    
      console.log(data)

  return (
    <div className='mt-2 mb-2 p-4 bg-white rounded-md'>
        <div className='text-2xl'>
            {data.blog.data.attributes.Title}
        </div>

        <div className='mt-2 mb-2'>
            {data.blog.data.attributes.Body}
        </div>

        <div className=''>
            <p className='text-purple-500'>Blog Author: {data.blog.data.attributes.Author}</p>
        </div>
    </div>
  );
}

代码解释。

  • 在上面的代码中,我们使用useParams() 钩子来从URL中获取参数。

  • 然后我们使用useQuery() 钩子来传递我们要获取的博客的id ,执行查询并将结果存储在一个对象中。

  • 在成功获取数据后,我们将其显示在网页上。

最后,打开App.js 文件,粘贴下面的代码。

//Make the necessary imports
import Header from "./components/Header";
import Homepage from "./pages/Homepage";
import BlogDetails from "./pages/BlogDetails";

import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client"

import {
  BrowserRouter,
  Routes,
  Route
} from "react-router-dom";

// initialize apollo client
const client = new ApolloClient({
  uri: 'http://localhost:1337/graphql',
  cache: new InMemoryCache()
})

function App() {
  return (
    <BrowserRouter>
      <ApolloProvider client={client}>
        <div className="w-screen bg-gray-100 h-screen overflow-y-auto">
          <div className="w-4/5 mx-auto mt-4"> 
            <Header />
            <Routes>
              <Route path="/" element={<Homepage />} />
              <Route path="blog/:id" element={<BlogDetails />} />
            </Routes>
          </div>
        </div>
      </ApolloProvider>
    </BrowserRouter>
  );
}

export default App;

代码解释。

  • 在上面的代码中,我们初始化了Apollo客户端,并将一个配置对象与uricache

  • uri 是用来指定我们的GraphQL服务器的URL。 ,指定Apollo Client在获取查询结果后将缓存在哪里。cache

  • 然后我们以正确的顺序包装一切,并设置路由。

测试应用程序

为了测试应用程序,通过运行React应用程序来启动它。

npm start

确保Strapi的后端也在运行。如果没有,就用 "运行 "来运行它。

npm run develop

现在在浏览器上打开localhost:3000 。你会看到以下内容。

All Blogs

注意,根据你放在后台的内容,内容会有所不同。

在点击Read more... ,将显示以下页面。

Single Blog

这表明路由的工作是正确的。

总结

在本教程中,我们已经介绍了如何使用Strapi和React创建一个博客网络应用。我们还讨论了如何使用GraphQL从后端获取我们需要的确切数据,并使用TaiwindCSS为我们的Web应用设计样式。