介绍
今天和今天,我都在开发用于前端React和后端Rails的SPA API应用程序
在TypeScript的React端,我认为react-apollo的类型声明很烦人。
由于GraphQL用于后端,因此感觉就像您在各个地方声明类型一样,这很微妙。 ..
因此,我将讨论使用graphql-code-generator解决各种不愉快的部分。
这个配置
前端
GitHub
- 反应(在SPA中)
- typescript
- 创建反应应用
- 反应阿波罗
后端
GitHub
- ruby
- Rails(带有API)
- GraphQL
*以上两个存储库是从此存储库链接的。 (作为开发环境)
目前,请尝试按照阿波罗官方提供的
我已经在后端创建了一个名为
在前端获取并显示它。
src / App.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | +import { gql, useQuery } from "@apollo/client"; import React from "react"; import logo from "./logo.svg"; import "./App.css"; +const TODOS_QUERY = gql` + query { + todos { + name + } + } +`; const App = () => { + const { loading, data } = useQuery(TODOS_QUERY); + return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p><center>[wp_ad_camp_2]</center></p><p> Edit <wyn>src/App.tsx</wyn> and save to reload. </p> - <a - className="App-link" - href="https://reactjs.org" - target="_blank" - rel="noopener noreferrer" - > - Learn React - </a> + {loading ? ( + <p>Loading ...</p> + ) : ( + <ul> + {data && data.todos.map(({ name }, i) => <li key={i}>{name}</li>)} + </ul> + )} </header> </div> ); }; export default App; |
我没有声明
类型,所以出现错误。
我将声明
类型。
准备的类型是
响应返回值
1 2 3 4 5 6 7 | interface Todo { name: string; } interface TodosData { todos: Todo[]; } |
如下使用
1 2 | - const { loading, data } = useQuery(TODOS_QUERY); + const { loading, data } = useQuery<TodosData>(TODOS_QUERY); |
我能够执行而没有错误。
在
中,让我们看看如果包含
使用GraphQL代码生成器
根据官方步骤
安装和设置
https://graphql-code-generator.com/docs/getting-started/codegen-config
1 | $ yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations |
package.json
1 2 3 | "scripts": { "generate": "graphql-codegen" } |
在后端侧准备的末端波恩是
程式码
1 2 3 4 5 6 7 | schema: http://localhost:5000/graphql documents: ./graphql/queries/*.graphql generates: ./src/types.d.ts: plugins: - typescript - typescript-operations |
*使用
在
graphql /查询/ todos.graphql
1 2 3 4 5 | query { todos { name } } |
在
后端运行时,尝试执行准备好的
1 | $ yarn generate |
src / types.d.ts
1 2 3 4 5 6 7 8 9 10 11 12 | ...省略... export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; export type Unnamed_1_Query = ( { __typename?: 'Query' } & { todos: Array<( { __typename?: 'Todo' } & Pick<Todo, 'name'> )> } ); |
因为它是
graphql /查询/ todos.graphql
1 2 3 4 5 6 | -query { +query todos { todos { name } } |
在
让我们将其用于
src / App.tsx
1 2 3 4 | + import { TodosQuery } from "./types.d"; - const { loading, data } = useQuery<TodosData>(TODOS_QUERY); + const { loading, data } = useQuery<TodosQuery>(TODOS_QUERY); |
我能够以相同的方式确认操作。
不再需要在
但是编写查询以在两个位置
如果我有专用的
介绍@ graphql-codegen / typescript-react-apollo
如果我有专用的
通过说
,我们将消除这种不愉快的感觉。
首先安装
1 | $ yarn add -D @graphql-codegen/typescript-react-apollo |
添加
程式码
1 2 3 4 5 6 7 8 | schema: http://localhost:5000/graphql documents: ./graphql/queries/*.graphql generates: ./src/types.d.ts: plugins: - typescript - typescript-operations + - typescript-react-apollo |
执行生成命令
1 | $ yarn generate |
在
src / App.tsx
1 2 3 4 5 | - import { TodosQuery } from "./types.d"; + import { useTodosQuery } from "./types.d"; - const { loading, data } = useQuery<TodosQuery>(TODOS_QUERY); + const { loading, data } = useTodosQuery(); |
它正常工作。
GraphQL的便利之一是,即使使用相同的API,也只能获取所需的字段。
早先,当获取
要实现单独编辑和删除等功能,除非
您需要标识
如果在另一个屏幕上除
1 2 3 4 5 6 | query todos { todos { id name } } |
但是,
因为已经有一个查询函数仅指定
当我运行
graphql /查询/ todosIncludeId.graphql
1 2 3 4 5 6 | query todos { todos { id name } } |
graphql /查询/ todosIncludeId.graphql
1 2 3 4 5 6 7 | -query todos { +query todosIncludeId { todos { id name } } |
我将
然后,除
您可以使用GraphQL而不破坏其有用的特性。
参考
- 阿波罗文件
- Graphql代码生成器-入门
- 使用graphql-codegen(React,Apollo,TypeScript)--Qiita生成类型定义
- 如何使用GraphQL代码生成器。 ?从GraphQL Schema自动生成TS类型定义?
- Graphql代码生成器--typescript-react-apollo