资讯专栏INFORMATION COLUMN

react+graphql起手和特性介绍(三)

soasme / 2585人阅读

摘要:如果你对这系列文章有疑问或发现有错误的地方,欢迎在下方留言讨论。

紧接上篇react+graphql起手和特性介绍(二),介绍完graphql与koa的服务搭建和graphql的一些常用特性,接下来我们介绍下在react中如何使用graphql
我们使用create-react-app创建react应用:

</>复制代码

  1. npm i -g create-react-app
  2. mkdir react-graphql-app
  3. create-react-app react-graphql-app

安装以下前端依赖

</>复制代码

  1. npm install react-apollo graphql-tag graphql apollo-client apollo-cache-inmemory apollo-link-http

各个依赖包的作用:

apollo-link-http 请求配置和网络请求能力

apollo-cache-inmemory 数据缓存

apollo-client 请求流程控制,生成请求数据,错误控制,响应数据解析

graphql-tag 查询类的schema数据解析,包含对应的 webpack-loader

react-apollo 连接graphql与react

graphql 提供graphql的核心执行能力

然后我们进行react和graphql的整合

</>复制代码

  1. // src/index.js
  2. import React from "react";
  3. import ReactDOM from "react-dom";
  4. import { ApolloClient } from "apollo-client";
  5. import { createHttpLink } from "apollo-link-http";
  6. import { InMemoryCache } from "apollo-cache-inmemory";
  7. import { ApolloProvider } from "react-apollo";
  8. import App from "./App";
  9. // 我们可以自定义fetch,对请求进行统一处理
  10. const customFetch = (uri, options) => {
  11. return fetch(uri, options);
  12. };
  13. const client = new ApolloClient({
  14. // 连接到graphql服务器
  15. link: createHttpLink({ uri: "http://localhost:9191/graphql", fetch: customFetch }),
  16. // 设置缓存
  17. cache: new InMemoryCache(),
  18. });
  19. // ApolloProvider 为react提供graphql能力
  20. const WrappedApp = (
  21. );
  22. ReactDOM.render(WrappedApp, document.getElementById("root"));

为了能解析.graphql文件,需要修改webpack配置,添加graphql-loader

</>复制代码

  1. // config/webpack.config.dev.js && config/webpack.config.prod.js
  2. ...
  3. module.exports = {
  4. ...
  5. module: {
  6. strictExportPresence: true,
  7. rules: [
  8. ...
  9. {
  10. // 解析 .graphql/.gql 后缀的loader
  11. test: /.(graphql|gql)$/,
  12. exclude: /node_modules/,
  13. loader: "graphql-tag/loader",
  14. },
  15. ...
  16. ]
  17. }
  18. ...
  19. }

我们以post为示例,讲一下在组件中要做什么操作
创建定义查询的schema文件

</>复制代码

  1. # src/post.graphql
  2. # 导入 user.graphql
  3. #import "./user.graphql"
  4. # fragment 定义片段,可以用于多个地方
  5. fragment PostInfo on Post {
  6. id
  7. title
  8. content
  9. userId
  10. user {
  11. ...UserInfo
  12. }
  13. }
  14. query getPost($id: ID!) {
  15. post(id: $id) {
  16. id
  17. title
  18. content
  19. userId
  20. user {
  21. id
  22. name
  23. age
  24. available
  25. birthday
  26. money
  27. gender
  28. }
  29. }
  30. }
  31. query getPosts {
  32. posts {
  33. ...PostInfo
  34. }
  35. }
  36. mutation createPost($data: PostInput!) {
  37. createPost(data: $data) {
  38. ...PostInfo
  39. }
  40. }

</>复制代码

  1. # src/user.graphql
  2. fragment UserInfo on User {
  3. id
  4. name
  5. age
  6. available
  7. birthday
  8. tags
  9. gender
  10. role
  11. }

</>复制代码

  1. // src/App.js
  2. import React, { Component } from "react";
  3. import Post from "./Post";
  4. class App extends Component {
  5. render() {
  6. return (
  7. );
  8. }
  9. }
  10. export default App;

</>复制代码

  1. // src/Post.js
  2. import React, { Component } from "react";
  3. import { Query, Mutation, ApolloConsumer } from "react-apollo";
  4. // 导入查询定义,定义的查询名次对应导入对象的方法名称,如 getPost => postQuery.getPost
  5. import postQuery from "./post.graphql";
  6. class Post extends Component {
  7. state = {
  8. post: {},
  9. postId: "",
  10. newPost: {
  11. title: "",
  12. content: "",
  13. }
  14. }
  15. render() {
  16. // 由ApolloConsumer传入我们需要的数据,包含:
  17. // data 正常返回时的数据
  18. // loading 正在请求时loading会为true
  19. // error 发生错误时error将会有错误数据
  20. // 这里进行了重命名,将创建post,获取posts列表进行了命名区分
  21. const {
  22. client,
  23. getPostsData, getPostsDataLoading,
  24. createPost, createPostData, createPostLoading,
  25. getPostsDataError
  26. } = this.props;
  27. const { postId, post, newPost } = this.state;
  28. return(
  29. {
  30. // loading状态时将显示...
  31. getPostsDataLoading ?
  32. ...
  33. :
  34. (
  35. getPostsDataError ?
  36. // 有错误数据,将会显示错误
  37. {JSON.stringify(getPostsDataError)}
  38. :
  39. // 正常则显示请求到的数据
  40. {JSON.stringify(getPostsData.posts)}
  41. )
  42. }

  43. {
  44. this.setState({ postId: e.target.value })
  45. }}
  46. />
  47. // client 也是props传过来的对象,可以让我们主动发起请求
  48. client.query({
  49. // 对应定义的 getPost 查询
  50. query: postQuery.getPost,
  51. // 设置请求参数
  52. variables: {
  53. id: postId
  54. }
  55. }).then(({ data: { post } }) => {
  56. this.setState({
  57. post
  58. })
  59. })
  60. }}>
  61. getPost
  62. {JSON.stringify(post)}

  63. this.setState({
  64. newPost: {
  65. ...newPost,
  66. title: e.target.value,
  67. }
  68. })}
  69. />
  70. this.setState({
  71. newPost: {
  72. ...newPost,
  73. content: e.target.value,
  74. }
  75. })}
  76. />
  77. // createPost是ApolloConsumer传过来的包装好的请求方法,
  78. // 这里只用设置请求参数,loading,data,error 将会通过props
  79. // 传递进来
  80. variables: {
  81. data: newPost
  82. }
  83. })}>
  84. createPost
  85. {
  86. createPostLoading ?
  87. ...
  88. :
  89. {JSON.stringify(createPostData && createPostData.createPost)}
  90. }
  91. )
  92. }
  93. }
  94. class PostWrap extends Component {
  95. render() {
  96. return (
  97. {(client) => (
  98. // 传入要使用的motation查询
  99. {(
  100. // 方法重命名
  101. createPost,
  102. {
  103. // 状态数据重命名
  104. data: createPostData,
  105. loading: createPostLoading
  106. }
  107. ) => (
  108. // 当同时多个查询时,使用这种嵌套模式
  109. {({
  110. // 状态数据重命名
  111. data: getPostsData,
  112. loading: getPostsLoading,
  113. error: getPostsDataError
  114. }) =>
  115. // 将重命名的状态数据和查询方法传递到组件中
  116. // Query指定的查询在组件加载后就会自动发起请求
  117. }
  118. )}
  119. )}
  120. )
  121. }
  122. }
  123. export default PostWrap;

通过这种方式我们可以在react中使用graphql了,这种方式极大方便了我们对请求数据api的管理,而且可以通过整合查询,减少页面的请求次数。
如果你对这系列文章有疑问或发现有错误的地方,欢迎在下方留言讨论。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99661.html

相关文章

  • react+graphql手和特性介绍(二)

    摘要:紧接第一篇文章,起手和特性介绍一,我们接下来实现,和自定义请求上下文,来完成创建用户,发帖,查看所有帖子的功能首先,我们进行自定义请求上下文,来模拟数据库和会话,保存我们的用户数据,帖子数据,登录状态。 紧接第一篇文章,react+graphql起手和特性介绍(一),我们接下来实现resolver,和自定义请求上下文,来完成创建用户,发帖,查看所有帖子的功能首先,我们进行自定义请求上下...

    NikoManiac 评论0 收藏0
  • 前端每周清单第 10 期:Firefox53、React VR发布、Microsoft Edge现代

    摘要:新闻热点国内国外,前端最新动态发布近日,正式发布新版本中提供了一系列的特性与问题修复。而近日正式发布,其能够帮助开发者快速构建应用。 前端每周清单第 10 期:Firefox53、React VR发布、JS测试技术概述、Microsoft Edge现代DOM树构建及性能之道 为InfoQ中文站特供稿件,首发地址为这里;如需转载,请与InfoQ中文站联系。从属于笔者的 Web 前端入门...

    MingjunYang 评论0 收藏0
  • 前端每周清单年度总结与盘点

    摘要:前端每周清单年度总结与盘点在过去的八个月中,我几乎只做了两件事,工作与整理前端每周清单。本文末尾我会附上清单线索来源与目前共期清单的地址,感谢每一位阅读鼓励过的朋友,希望你们能够继续支持未来的每周清单。 showImg(https://segmentfault.com/img/remote/1460000010890043); 前端每周清单年度总结与盘点 在过去的八个月中,我几乎只做了...

    jackwang 评论0 收藏0
  • 前端每周清单:Node.js 微服务实践,Vue.js 与 GraphQL,Angular 组件技巧

    摘要:前端每周清单第期微服务实践,与,组件技巧,攻防作者王下邀月熊编辑徐川前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 前端每周清单第 26 期:Node.js 微服务实践,Vue.js 与 GraphQL,Angular 组件技巧,HeadlessChrome 攻防 作者:王下邀月熊 编辑:徐川...

    wall2flower 评论0 收藏0
  • 王下邀月熊_Chevalier的前端每周清单系列文章索引

    摘要:感谢王下邀月熊分享的前端每周清单,为方便大家阅读,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清单系列,并以年月为单位进行分类,具体内容看这里前端每周清单年度总结与盘点。 感谢 王下邀月熊_Chevalier 分享的前端每周清单,为方便大家阅读,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清单系列,并以年/月为单位进行分类,具...

    2501207950 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<