全栈 React + GraphQL 教程(一)

首发于众成翻译javascript


Part 1——前端:使用 Apollo 声明式地请求和 mock 数据

GraphQL 是一种新的 API 定义和查询语言,有可能成为新的 REST。它使 UI 组件易于声明式地获取数据,而没必要关注后端实现细节。GraphQL 做为一种强大的抽象,能够加快应用开发速度,使代码更容易维护。css

然而,尽管使用 GraphQL 有诸多好处,但迈出第一步可能并不容易。这就是为何我编写了这一系列教程,带你一步步地编写一个包含 GraphQL 和 Apollo Client 的全栈 React 应用。该系列将引导你完整构建一个使用 GraphQL 的即时消息应用:html

本教程——做为这一系列中的第一篇——是关于如何在前端开始使用 GraphQL。只须要大约20-30分钟,最终你会获得一个很是简单的 React UI,它使用 GraphQL 加载数据,看起来像这样:前端

一个使用 GraphQL 加载数据的简易 React UIjava

让咱们开始吧!node

1. 环境搭建

注意:要完成此教程,你须要在你的机器上安装 node,npm 和 git,而且对 React 有所了解。react

咱们将在本教程中使用 create-react-app,因此执行安装:git

> npm install -g create-react-app

咱们还须要从 GitHub 中克隆本教程的代码库,其中包含了咱们稍后会使用到的 CSS 和图像。github

> git clone https://github.com/apollographql/graphql-tutorial.git
> cd graphql-tutorial

接下来,咱们使用 create-react-app 建立咱们的 react 应用。npm

> create-react-app client
> cd client

为了确保它能工做,咱们启动服务器:

> npm start

若是一切正常,你如今应该在浏览器中看到以下内容:

2. 编写第一个组件

因为咱们正在使用 Apollo 构建一个应用,因此咱们经过从 ../ resources 复制 logo.svgApp.css 来修改 logo 和 CSS。

> cd src
> cp ../../resources/* .

为了简化初始教程,咱们今天只构建一个简单的列表视图。让咱们修改 App.js 中的代码:

  1. 修改 “Welcome to React” 为 “Welcome to Apollo”。Apollo 是咱们将在本教程系列中使用的 GraphQL 客户端的名称。
  2. 删除 “To get started ..”段落,并用纯 React 组件替换它,该组件将渲染一个具备两个列表项的无序列表,“Channel 1”和 “Channel 2”(是的,你猜到了,咱们要构建一个通讯应用!)。咱们将列表组件命名为 ChannelsList

如今你的 App.js 应该以下所示:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const ChannelsList = () =>
     (<ul>
       <li>Channel 1</li>
       <li>Channel 2</li>
     </ul>);
class App extends Component {
   render() {
     return (
       <div className="App">
         <div className="App-header">
           <img src={logo} className="App-logo" alt="logo" />
           <h2>Welcome to Apollo</h2>
         </div>
         <ChannelsList />
       </div>
     );
   }
 }
export default App;

create-react-app 为你设置好了热加载,因此一旦你保存文件,你的应用所在的浏览器窗口将会更新以反映更改:

若是看起来像这样,你的设置就是正确的。

3. 编写你的 GraphQL schema

如今咱们有一个简单的应用正在运行,如今是为它编写 GraphQL 类型定义的时候了。 Schema 将指定咱们的应用中存在哪些对象类型,以及它们有哪些字段。此外,它指定了咱们的 API 的入口。咱们新建一个名为 schema.js 的文件:

export const typeDefs = `
type Channel {
   id: ID!                # "!" 为必填
   name: String
}
# 此类型指定了咱们的 API 的入口点。在本例中,只有一个——"channels"——返回频道列表。
type Query {
   channels: [Channel]    # "[]" 意味着这是频道列表
}
`;

有了这个 schema,咱们能够在下节中编写一个简单的查询来获取咱们的 ChannelList 组件的数据。这是咱们的查询:

query ChannelsListQuery {
  channels {
    id
    name
  }
}

4. 将你的组件链接 GraphQL 查询

好,如今咱们有了 schema 和查询,咱们只须要使用 Apollo Client 链接咱们的组件!咱们来安装 Apollo Client 和一些辅助软件包,咱们须要将 GraphQL 添加到咱们的应用中:

> npm i -S react-apollo

react-apollo 是 Apollo Client 与 React 的整合,可让你使用名为 graphql高阶组件来装饰组件,它将你的 GraphQL 数据不费力地导入到组件中。React Apollo 还提供了 ApolloClient,它是 Apollo 的核心,处理全部数据获取,缓存和积极更新(咱们将在另外一个教程中讨论)。

如今,咱们在 App.js 的顶部添加一些导入,并建立一个 Apollo Client 的实例:

import {
  ApolloClient,
  gql,
  graphql,
  ApolloProvider,
} from 'react-apollo';
const client = new ApolloClient();

接下来,咱们使用 GraphQL 高阶组件来装饰原来的 ChannelsList,该高阶组件接受查询并将数据传递给咱们的组件:

const channelsListQuery = gql`
   query ChannelsListQuery {
     channels {
       id
       name
     }
   }
 `;
const ChannelsListWithData = graphql(channelsListQuery)(ChannelsList);

当咱们的 ChannelsList 组件使用 graphql HOC 包装时,将会收到一个名为 data 的 prop,当它可用时会包含 channel,当有错误时会显示 error。另外 data 还包含一个 loading 属性,当 Apollo Client 在等待数据获取的时候它的值为 true

接下来修改咱们的 ChannelsList 组件,以确保用户知道该组件是否正在加载,或者是否出现错误:

const ChannelsList = ({ data: {loading, error, channels }}) => {
   if (loading) {
     return <p>Loading ...</p>;
   }
   if (error) {
     return <p>{error.message}</p>;
   }
return <ul>
     { channels.map( ch => <li key={ch.id}>{ch.name}</li> ) }
   </ul>;
 };

最后,咱们用 ChannelsListWithData 替换 App 的 render 函数中的 ChannelsList。 为了让咱们刚建立的组件可以使用 Apollo Client 的实例,咱们用 ApolloProvider 包裹顶级的应用组件,这会将 Apollo Client 的一个实例放在 UI 上。

如今你的 App 组件应该以下所示:

class App extends Component {
   render() {
     return (
       <ApolloProvider client={client}>
         <div className="App">
           <div className="App-header">
             <img src={logo} className="App-logo" alt="logo" />
             <h2>Welcome to Apollo</h2>
           </div>
           <ChannelsListWithData />
         </div>
       </ApolloProvider>
     );
   }
 }

好的,咱们快完成了!若是你如今尝试运行,应该会看到如下错误:

起做用了!——好吧,至少部分如此。

这是怎么回事?尽管咱们正确地链接了全部的组件,但咱们尚未写一个服务器,因此固然没有数据能够获取或显示! 若是你没有为 GraphQL 端点指定 URL,Apollo Client 将假定它运行在同一个域下的 /graphql。所以咱们须要建立一个具备自定义 URL 的网络接口。

可是,因为本教程不是关于编写服务器的,因此咱们将利用 GraphQL 代码即文档这一特性,根据咱们先前写过的类型定义自动建立 mock。要实现这一点,咱们只须要中止服务器,安装一些其余的软件包,而后从新启动它:

npm i -S graphql-tools apollo-test-utils graphql

咱们将使用这些软件包根据咱们前面写的 schema 为 Apollo Client 建立一个模拟网络接口。将如下导入和定义添加到 App.js 的顶部:

import { 
  makeExecutableSchema,
  addMockFunctionsToSchema
} from 'graphql-tools';
 import { mockNetworkInterfaceWithSchema } from 'apollo-test-utils';
 import { typeDefs } from './schema';
const schema = makeExecutableSchema({ typeDefs });
addMockFunctionsToSchema({ schema });
const mockNetworkInterface = mockNetworkInterfaceWithSchema({ schema });

如今你只需将 mockNetworkInterface 传递给 Apollo Client 的构造函数:

const client = new ApolloClient({
   networkInterface: mockNetworkInterface,
 });

就是这样,你已经完成了!你的屏幕如今应该以下所示:

咱们作到了,咱们的第一个使用 Apollo 的 React + GraphQL 应用!

注意:“Hello World” 只是字符串的默认模拟文本。 若是你想自定义酷炫的 mock,请查看我以前写的这篇文章

若是某些代码不起做用,而且你搞不清是为何,你能够将其与此文件进行比较,以发现代码差别。或者,你能够查看 t1-end Git 分支来检查代码。


恭喜,你已经正式完成了教程的第一部分!可能没什么感受,但实际上已经作了不少工做:你已经编写了一个 GraphQL schema,从中生成模拟数据,并将 GraphQL 查询与 React 组件相连。在本教程的其他部分中,你将了解到咱们构建一个真正的通讯应用的基础。在第2部分中,咱们将编写一个简单的服务器并将其链接到咱们的应用!

相关文章
相关标签/搜索