如何使用GraphQL和Apollo构建一个宝可梦应用

宝可梦是一个由视频游戏、动画系列与电影、交换卡牌游戏以及其他相关媒体组成的日本媒体特许经营权。

在本文中,我们将使用一个宝可梦GraphQL API,该API提供有关不同宝可梦的数据。

我们将使用Apollo和GraphQL来处理数据获取,以及React来构建我们的前端应用程序。

如果您不了解这些技术,也不用担心,我将会在您阅读的过程中为您介绍基础知识。

(本文内容参考:java567.com)

先决条件

您的计算机上应该有以下内容以便跟着做:

  • Nodejs v18+
  • 一个代码编辑器
  • 一个网页浏览器

让我们创建我们的React应用程序。

React应用程序设置

要创建您的React应用程序,请转到您的终端,并使用命令提示符。打开您的命令提示符,并选择您喜欢创建React项目的位置。让我们选择桌面。

cd Desktop

上述命令将导航到您的桌面。

npm create vite@latest pokemon-app -- --template react

npm create vite@latest 将开始使用Vite构建一个新项目。但是,我们附加了我们项目的名称(pokemon-app)以及我们应用程序将使用的技术或框架(-- – template react)。

您可以设置另一个模板,如svelte、vanilla或vue,项目将使用该框架创建。在其官方网站上关于Vite的信息。

安装Vite之后,运行以下命令:

cd pokemon-app
npm install
npm run dev

我们将使用上述命令完成React设置。

运行第一个命令cd pokemon-app,以导航到pokeman-app文件夹。

运行code .来在您的代码编辑器中打开该文件夹。

在这里插入图片描述

如果弹出对话框要求信任文件的作者,请标记信任作者复选框。

打开您的代码编辑器终端。如果您在Windows上运行VSCode,则快捷键是`Ctrl + ``。

在终端中依次运行其他2个命令。

npm install
npm run dev

您的项目现在应该在浏览器中运行。

我们将使用GraphQL和Apollo来管理我们的数据获取。

如何使用GraphQL和Apollo

GraphQL是一种用于API的查询语言,也是用于使用现有数据执行查询的运行时。它允许您在应用程序中仅请求所需的数据,而不多余,从而使其非常高效和灵活。

Apollo是一个状态管理库,允许您使用GraphQL管理本地和远程数据。它可用于获取、缓存和修改应用程序数据,同时自动更新您的UI。

让我们安装您需要的包。

安装包

在您的终端中运行以下命令以安装Apollo客户端。

npm install @apollo/client

导航到您的main.jsx文件并导入以下内容:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import {ApolloProvider,ApolloClient,InMemoryCache,
} from "@apollo/client";
import "./index.css";

您已经导入了React和ReactDOM用于DOM操作。

ApolloClient负责管理您应用程序的数据获取和状态管理。它负责将GraphQL查询和变异发送到GraphQL服务器并缓存结果。

ApolloProvider将用于包装您的React应用程序,以向所有组件提供Apollo客户端实例,以便您的应用程序可以通过Apollo客户端访问获取的数据。

InMemoryCache是一个缓存实现,用于将GraphQL查询的结果存储在内存中,以便高效地访问和检索。

您还导入了index.css来为您的应用程序设置样式。

如何创建Apollo客户端

const client = new ApolloClient({uri: "https://graphql-pokemon2.vercel.app/",cache: new InMemoryCache(),
});

以上代码使用了一些配置创建了ApolloClient的新实例:

  1. uri:这指定了您的GraphQL API端点的URL。这是您的Apollo客户端将发送GraphQL查询和变异的端点。
  2. cache:这配置了Apollo客户端的缓存实现,以使用内存缓存访问数据并存储GraphQL查询的结果,减少了从服务器重新获取数据的需要。

现在您可以将您的组件与ApolloProvider一起包装:

ReactDOM.createRoot(document.getElementById("root")).render(<React.StrictMode><ApolloProvider client={client}><App /></ApolloProvider></React.StrictMode>
);

请注意,client属性也被传递以提供您的应用程序ApolloClient的配置。

转到您的App.jsx组件并输入以下内容:

import React from "react";
import { PokemonsContainer } from "./components/PokemonsContainer";export default function App() {return (<main><PokemonsContainer /></main>);
}

您导入了React和将要创建的PokemonsContainer。PokemonsContainer组件被包装在main标签中,并将在组件粘贴到DOM中时呈现。

让我们在位于components文件夹中的文件中创建PokemonsContainer组件。即:

📂 src/components/PokemonsContainer.jsx

Pokemons Container组件

import React from "react";
import { useQuery } from "@apollo/client";
import { Pokemon } from "../components/Pokemon";
import { GET_POKEMONS } from "../graphql/get-pokemons";

来自@apollo/client的useQuery用于在Apollo应用程序中执行查询。为此,调用useQuery()并将GraphQL查询字符串作为参数传递。当您的组件渲染时,useQuery返回一个包含loading、error和data属性的对象,您可以使用这些属性来呈现您的UI。

导入了Pokemon组件以渲染Pokemon的用户界面,这将很快构建。

也导入了GET_POKEMONS。这将包含一个GraphQL查询。

在导入了上述函数之后,继续构建您的页面。

export function PokemonsContainer() {const { loading, error, data } = useQuery(GET_POKEMONS, {variables: { first: 5 },});if (loading) return <p>Loading...</p>;if (error) return <p>Error: {error.message}</p>;const pokemons = data?.pokemons || [];return (<div className="container">{pokemons &&pokemons.map((pokemon) => (<Pokemon key={pokemon.id} pokemon={pokemon} />))}</div>);
}

如前所述,useQuery返回一个包含loading、error和data属性的对象。它们在此处被解构,因此您可以在页面中访问它们。

请注意,我们为useQuery挂钩提供了一个配置选项(variables)。第二个参数也传递了{ variables: { first: 5 } }。variables选项是一个对象,其中包含我们要传递给GraphQL查询的所有变量。在这种情况下,我们传递了一个对象{ first: 5 }来指定我们要获取前五个Pokemons。

如果查询仍在加载中,则返回

Loading…

以通知用户,如果有错误,则返回

Error: {error.message}

创建了pokemons常量以保存数据对象的Pokemons属性的值。如果data.pokemons不可用,则pokemons常量将是一个空数组。

返回一个具有container类名的div,该div检查pokemons是否可用,并将数组映射到Pokemon组件。

让我们创建Pokemon组件:

📂src/components/Pokemon.jsx

宝可梦组件

import React from "react";export function Pokemon({ pokemon }) {return (<div className="pokemon"><div className="pokemon__name"><p>{pokemon.name}</p></div><div className="pokemon__meta"><span>{pokemon.maxHP}</span><span>{pokemon.maxCP}</span></div><div className="pokemon__image"><img src={pokemon.image} alt={pokemon.name} /></div><div className="pokemon__attacks">{pokemon.attacks.special.slice(0, 3).map((attack) => (<span key={`${attack.name}-${attack.damage}`}>{attack.name}</span>))}</div></div>);
}

此处定义了宝可梦实例的结构,具有用于样式化的类名。将呈现名称、最大HP、最大CP、图像和攻击数组。

让我们创建GET_POKEMONS GraphQL查询。

📂src/graphql/get-pokemons

GraphQL 查询

import gql from "graphql-tag";export const GET_POKEMONS = gql`query pokemons($first: Int!) {pokemons(first: $first) {idnameimagemaxHPmaxCPattacks {special {namedamage}}}}
`;

您从graphql-tag导入了gql并创建了一个名为GET_POKEMONS的GraphQL查询。

将pokemons查询函数包装在字符串中,以便gql函数将它们解析为查询文档。

$first: Int! 表示您的查询期望一个名为first的变量,它是一个整数,! 符号表示该变量是必需的。

回想一下,我们在PokemonsContainer组件中创建了variables对象,在下面有这个对象。

 const { loading, error, data } = useQuery(GET_POKEMONS, {variables: { first: 5 },});

也声明了pokemons(first: f i r s t ) 。这里将 first)。这里将 first)。这里将first分配给了5(我们在上面的代码段中传入了9)。因此,数组将只包含5个对象。每个对象将包含id、name、image、maxHP、maxCP和攻击对象,该对象将包含特殊对象,其中包含name和damage。

GraphQL服务器可能包含更多属性,但只会返回上述列出的属性。这是GraphQL的一个很酷的功能——它只返回您请求的数据。

样式化我们的应用程序

您的index.css应该包含以下内容:

/* 重置
=========================================== */
html {-webkit-box-sizing: border-box;box-sizing: border-box;
}*,
*:before,
*:after {-webkit-box-sizing: inherit;box-sizing: inherit;
}body {margin: 20px 0;padding: 0 20px;line-height: 1;font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;color: #202020;background-color: #fbfbfb;font-smooth: always;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}/* 宝可梦应用程序
=========================================== */
.container {display: flex;max-width: 80%;margin: auto;height: 100vh;justify-content: space-between;align-items: center;gap: 10px;
}.container p {margin: 0;
}.container .pokemon {width: 20%;background-color: #fff;background-clip: border-box;border: 1px solid rgba(0, 0, 0, 0.125);border-radius: 0.25rem;box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);overflow: hidden;/* margin: 5px; */
}.container .pokemon__name {background-color: #ecd018;text-align: center;padding: 10px;
}.container .pokemon__name p {text-transform: uppercase;font-weight: bold;color: white;letter-spacing: 4px;text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.4);
}.container .pokemon__image {padding: 20px;min-height: 300px;display: flex;align-items: center;justify-content: center;
}.container .pokemon__image img {max-width: 100%;height: auto;
}.container .pokemon__attacks {display: flex;padding-left: 10px;padding-right: 10px;justify-content: space-between;
}.container .pokemon__attacks span {width: 32%;background-color: #f16820;border-radius: 3px;padding: 7px;font-weight: 700;color: #fff;padding-left: 10px;padding-right: 10px;font-size: 12px;margin-bottom: 10px;word-wrap: break-word;text-align: center;line-height: 15px;
}.container .pokemon__meta {display: flex;justify-content: space-between;margin-top: 10px;padding: 0 10px;
}.container .pokemon__meta span {color: white;text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.4);background-color: #7bb7b7;font-weight: bold;margin: 0;padding: 5px 20px;border-radius: 5px;
}

一切正常,您应该在浏览器中看到以下内容:

显示了浏览器中五个宝可梦数据的图片

在这里插入图片描述

结论

就这样了。我希望您在这里找到了价值,学到了更多有关网络的知识。

如果您喜欢本文,并希望看到更多与JavaScript和Web开发相关的内容,别忘了点赞和关注。

谢谢,再见。

(本文内容参考:java567.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/798478.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谨慎使用通过光纤传输的HDMI光纤线,存严重缺陷

严重缺陷&#xff1a; 1.只能单向传输 只能单向传输&#xff0c;从一端到另一端&#xff0c;和二极管一样&#xff0c;只能单向传输信号。某些情况你需要变更传输方向时&#xff0c;你将欲哭无泪.传统的HDMI线&#xff0c;不带放大器的&#xff0c;都可以双向传输.网上搜索布…

Vue3【进阶】

简介 https://cn.vuejs.org/guide/introduction.html 创建vue3工程 【基于 vue-cli创建】 基本和vue-cli的过程类似&#xff0c;只是选择的时候用vue3创建 【基于vite创建】【推荐】 【官网】https://vitejs.cn/ 【可以先去学一下webpack】 步骤 【https://cn.vitejs.…

#QT项目实战(天气预报)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a; 3.记录&#xff1a; &#xff08;1&#xff09;调用API的Url a.调用API获取IP whois.pconline.com.cn/ipJson.jsp?iphttp://whois.pconline.com.cn/ipJson.jsp?ip if(window.IPCallBack) {IPCallBack({"ip":&quo…

华为海思2024春招数字芯片岗机试题(共9套)

huawei海思2024春招数字芯片岗机试题(共9套&#xff09;&#xff08;WX:didadidadidida313&#xff0c;加我备注&#xff1a;CSDN huawei数字题目&#xff0c;谢绝白嫖哈&#xff09; 题目包含数字集成电路、System Verilog、Verilog2001、半导体制造技术、高级ASIC芯片综合、…

Java实现二叉树(上)

1.树型结构 1.1树型结构的概念 树是一种 非线性 的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09;个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看 起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的 1.2树型结构的特点…

二 maven构建项目

一 Maven的GAVP Maven工程相对之前的工程&#xff0c;多出一组gavp属性&#xff0c;gav需要我们在创建项目的时指定&#xff0c;p有默认值&#xff0c;后期通过配置文件修改。 GAVP是指 GroupId、ArtifactId、Version、Packaging 等四个属性的缩写&#xff0c;其中前三个是必…

c++的学习之路:14、list(1)

本章讲一下如何使用list&#xff0c;代码在文章末 目录 一、list介绍 二、增 三、删 四、查和改 五、交换 六、代码 一、list介绍 首先还是看一看官方文档的介绍如下图&#xff0c;如下方五点&#xff1a; 1. list是可以在常数范围内在任意位置进行插入和删除的序列式…

element-ui result 组件源码分享

今日简单分享 result 组件的源码实现&#xff0c;主要从以下三个方面&#xff1a; 1、result 组件页面结构 2、result 组件属性 3、result 组件 slot 一、result 组件页面结构 二、result 组件属性 2.1 title 属性&#xff0c;标题&#xff0c;类型 string&#xff0c;无默…

网络基础三——初识IP协议

网络基础三 ​ 数据通过应用层、传输层将数据传输到了网络层&#xff1b; ​ 传输层协议&#xff0c;如&#xff1a;TCP协议提供可靠性策略或者高效性策略&#xff0c;UDP提供实时性策略&#xff0c;保证向下层交付的数据是符合要求的的&#xff1b;而网络层&#xff0c;如&a…

【动态规划-状态压缩dp】【蓝桥杯备考训练】:毕业旅行问题、蒙德里安的梦想、最短Hamilton路径、国际象棋、小国王【已更新完成】

目录 1、毕业旅行问题&#xff08;今日头条2019笔试题&#xff09; 2、蒙德里安的梦想&#xff08;算法竞赛进阶指南&#xff09; 3、最短Hamilton路径&#xff08;《算法竞赛进阶指南》&模板&#xff09; 4、国际象棋&#xff08;第十二届蓝桥杯省赛第二场C A组/B组&#…

Java初始——IDEA-web的启动

Tomcat 文件夹作用 bin 启动 关闭的脚本文件 conf 配置 lib 依赖的jar包 logs 日志 temp 临时文件 webapps 存放的网站 Maven 1.在javaweb中&#xff0c;需要使用大量的jar包&#xff0c;手动导入 2.Maven 架构管理工具 核心&#xff1a;约定大于配置 必须按照规则 web idea-we…

2024.4.7

1. 2列火车 #include<myhead.h>pthread_mutex_t m1; pthread_mutex_t m2;void* run(void* arg) {while(1){pthread_mutex_lock(&m1);printf("火车B进入\n");printf("A请等待\n");pthread_mutex_unlock(&m2);sleep(2);} }int main(in…

开发项目接单报价快速计算,报价量化程序

定制化开发&#xff0c;如何计算项目预算&#xff0c;是程序开发者头疼的一个问题。 项目费用谈得过低&#xff0c;就天天加班累死赚不到钱&#xff1b;谈得过高&#xff0c;会导致顾客流失&#xff0c;信誉受损。 项目费用量化可见是多么重要。 下面是一段量化的程序&#…

跟TED演讲学英文:AI isn‘t the problem — it‘s the solution by Andrew Ng

TED英文文稿 文章目录 TED英文文稿AI isnt the problem — its the solutionIntroductionVocabularyTranscriptSummary 2024年4月6日学习吴恩达的这篇演讲 AI isn’t the problem — it’s the solution Link: AI isn’t the problem — it’s the solution Speaker: Andrew …

C语言进阶课程学习记录-第21课 - 宏定义与使用分析

C语言进阶课程学习记录-第21课 - 宏定义与使用分析 宏定义的本质实验-字面量比较宏定义表达式实验-表达式有效性宏的作用域实验-作用域分析内置宏内置宏演示小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学…

人工智能 - 服务于谁?

人工智能服务于谁&#xff1f; 人工智能服务于生存&#xff0c;其最终就是服务于战争&#xff08;热战、技术战、经济战&#xff09; 反正就是为了活着而战的决策。 既然人工智能所有结果&#xff0c;来自大数据的分挖掘&#xff08;分析&#xff09;也就是数据的应用&#x…

自动驾驶中的交通标志识别原理及应用

自动驾驶中的交通标志识别原理及应用 附赠自动驾驶学习资料和量产经验&#xff1a;链接 概述 道路交通标志和标线时引导道路使用者有秩序使用道路&#xff0c;以促进道路行车安全&#xff0c;而在驾驶辅助系统中对交通标志的识别则可以不间断的为整车控制提供相应的帮助。比如…

Transformer位置编码详解

在处理自然语言时候&#xff0c;因Transformer是基于注意力机制&#xff0c;不像RNN有词位置顺序信息&#xff0c;故需要加入词的位置信息来显示的表明词的上下文关系。具体是将词经过位置编码(positional encoding)&#xff0c;然后与emb词向量求和&#xff0c;作为编码块(Enc…

CAS Server使用Maven构建以及自定义扩展使用

介绍 ​CAS&#xff08;Central Authentication Service&#xff09;中心授权/认证服务&#xff0c;是由耶鲁大学发起的一个开源项目&#xff0c;距今已有20年之久&#xff0c;功能相当丰富&#xff0c;目的在于为Web应用系统提供一种可靠且稳定的单点登录解决方案。 CAS分为…

Open CASCADE学习|在给定的TopoDS_Shape中查找与特定顶点 V 对应的TopoDS_Edge编号

enum TopAbs_ShapeEnum{TopAbs_COMPOUND,TopAbs_COMPSOLID,TopAbs_SOLID,TopAbs_SHELL,TopAbs_FACE,TopAbs_WIRE,TopAbs_EDGE,TopAbs_VERTEX,TopAbs_SHAPE}; 这段代码定义了一个名为 TopAbs_ShapeEnum 的枚举类型&#xff0c;它包含了表示不同几何形状类型的常量。这些常量通常…