当前位置:主页 > 资料 >

GraphQL 入门: Apollo Client API 之 graphql 容器
栏目分类:资料   发布日期:2017-05-28   浏览次数:

导读:本文为去找网小编(www.7zhao.net)为您推荐的GraphQL 入门: Apollo Client API 之 graphql 容器,希望对您有所帮助,谢谢! graphql() 函数是一个给组件增加数据逻辑(查询, 修改, 删除)的一个高阶函数

本文为去找网小编(www.7zhao.net)为您推荐的GraphQL 入门: Apollo Client API 之 graphql 容器,希望对您有所帮助,谢谢!

www.7zhao.net



去找(www.7zhao.net欢迎您

graphql() 函数是一个给组件增加数据逻辑(查询, 修改, 删除)的一个高阶函数, 存在于 react-apollo 模块中, 如果要使用它, 需要把它 import 进来. 欢迎访问www.7zhao.net

该函数接受一个React组件, 同时返回一个经过修改( 增加数据逻辑 )的React组件. 属于设计模式中的 装饰器模式 , 在不修改原组件的情况下, 对组件增加额外的功能, 实现了 「对修改关闭, 对扩展开放」 的软件工程原则. 本文来自去找www.7zhao.net

graphql 容器的基本形态如下:

本文来自去找www.7zhao.net

# 导入 graphql 函数
import { graphql } from 'react-apollo';
# 函数签名, 参数分别为GraphQL查询(通过`gql`进行构造, 一个可选的配置对象, 以及一个被包装的React组件)
graphql(query, [config])(component) 

内容来自www.7zhao.net

graphql() 函数有两个参数 本文来自去找www.7zhao.net

第一个参数为通过 qgl 包裹的查询字符串, 如:

本文来自去找www.7zhao.net

const TODO_QUERY = `query Todo {
  todos: {
    id
    text
  }
`} www.7zhao.net 

第二个参数为一个配置对象, 方括号表示其是可选的, 可省略

去找(www.7zhao.net欢迎您

第三个参数为被包装的React组件.

内容来自www.7zhao.net

graphql() 函数是 react-apollo 提供的最重要的一个函数. 用这个函数可以创建执行查询何更新的高阶组件. 去找(www.7zhao.net欢迎您

graphql() 函数可以这样用:

www.7zhao.net

function TodoApp({ data: { todos } }) {
  return (
    <ul>
      {todos.map(({ id, text }) => (
        <li key={id}>{text}</li>
      ))}
    </ul>
  );
}
export default graphql(gql`
  query TodoAppQuery {
    todos {
      id
      text
    }
  }
`)(TodoApp); www.7zhao.net 

也可以定义中间函数 内容来自www.7zhao.net

# 中间函数
const withTodoAppQuery = graphql(gql`query { ... }`);
# 传入React组件给这个中间函数
const TodoAppWithData = withTodoAppQuery(TodoApp);
# 导出这个组件
export default TodoAppWithData; 

本文来自去找www.7zhao.net

graphql() 函数也可以作为装饰器使用: 欢迎访问www.7zhao.net

@graphql(gql`
  query TodoAppQuery {
    todos {
      id
      text
    }
  }
`)
export default class TodoApp extends Component {
  render() {
    const { data: { todos } } = this.props;
    return (
      <ul>
        {todos.map(({ id, text }) => (
          <li key={id}>{text}</li>
        ))}
      </ul>
    );
  }
} 

欢迎访问www.7zhao.net

graphql() 函数的使用依赖于在React组件树的根外层再包装一个 <ApolloProvider/> 组件. <ApolloProvider /> 在其属性上提供了一个 ApolloClient 实例用于访问数据.

欢迎访问www.7zhao.net

通过 graphql() 函数增强的组件依据GraphQL的查询类型(Query, Mutation, Subscription)有不同的行为.

本文来自去找www.7zhao.net

配置对象

config.options

options 该对象可以是一个 纯对象 , 或者是一个 函数 . 用于定制GraphQL查询的行为, 比如, 给一个Mutation传递输入对象参数: copyright www.7zhao.net

内容来自www.7zhao.net

options: ({ params }) => ({
  variables: {
    text: '我是一个粉刷匠, 粉刷本领强4'
  },
}), 

欢迎访问www.7zhao.net

纯对象很简单, 形式为: 去找(www.7zhao.net欢迎您

const config = {
  name: 'getTodos'
} 本文来自去找www.7zhao.net 

options 函数, 接收一个组件属性作为参数, 形式为:

内容来自www.7zhao.net

export default graphql(TODO_QUERY, {
  options: (props) => ({
  }),
})(MyComponent); 

www.7zhao.net

config.props

该属性用于定义一个映射函数. 传入组件自身的属性, 和通过 graphql() 函数添加的属性(Query为, props.data , Mutation 为 props.mutate ), 这让我们能够构造一个新的属性对象, 并把这个 新的属性对象 传递给被 graphql() 包装的组件. copyright www.7zhao.net

config.props 的基本用途 www.7zhao.net

  • config.props 可以让我们把复杂的函数调用抽离成单独的模块, 并且作为简单的属性传递给组件. 本文来自去找www.7zhao.net

  • 从UI组件解耦 GraphQL 逻辑, 让UI组件更简单, 大体上讲就是UI组件只负责UI的渲染, config.props 选项用于封装复杂的数据处理逻辑. UI组件和数据交互逻辑实现分离, 并且通过 config.props 关联. 本文来自去找www.7zhao.net

config.name

这选项的作用是避免一个组件中有多个GraphQL查询, 或者Mutation名称上的冲突. 去找(www.7zhao.net欢迎您

我们方位GraphQL查询结果的数据通常是通过 this.props.data 放回数据的, data 属性是通过 graphql() 高阶函数注入到我们的组件属性中的, 这个名字有时候会和我们 组件本身 的属性名称冲突, 为了解决冲突问题, 可以在 graphql() 函数第二个参数配置对象中设置一个 name , 然后通过 this.props.${name} 来访问这个属性.

去找(www.7zhao.net欢迎您

export default compose(
  graphql(gql`mutation (...) { ... }`, { name: 'createTodo' }),
  graphql(gql`mutation (...) { ... }`, { name: 'updateTodo' }),
  graphql(gql`mutation (...) { ... }`, { name: 'deleteTodo' }),
)(MyComponent);
function MyComponent(props) {
  console.log(props.createTodo);
  console.log(props.updateTodo);
  console.log(props.deleteTodo);
  return null; 本文来自去找www.7zhao.net 

这样, 我们就可以通过 this.props.createTodo , this.props.updateTodo , this.props.deleteTodo 来访问我们需要的数据了.

内容来自www.7zhao.net

config.withRef

设置 config.withRef 为 true 时, 可以通过 graphql() 放回的高阶组件上调用 getWrappedInstance 方法获取被包装组件的实例. 通常我们需要访问 被包装组件 的属性和方法是需要把这个选项设置为 true , 默认为 false 内容来自www.7zhao.net

# 创建一个UI组件

class HelloWorld extends Component {
  saySomething() {
    console.log('Hello, world!');
  }
  render() {
  }
}

# 添加数据逻辑, 编程一个支持GraphQL的组件, 我们简称GraphQL组件

const HelloWorldWithData = graphql(
  gql`{ ... }`,
  { withRef: true },
)(HelloWorld);

# 使用 GraphQL 组件
# 通过该组件的ref属性, 我们能够访问到原始的 HelloWorld 组件实例

class Container extends Component {
  render() {
    return (
      <HelloWorldWithData ref={component => {
          assert(component.getWrappedInstance() instanceof HelloWorld);
          component.saySomething();
        }}
      />
    );
  }
} 
内容来自www.7zhao.net

config.alias

组件别名, 主要是给 React Devtools 使用, 用于区分多个不同的高阶组件 内容来自www.7zhao.net

export default compose(
  graphql(gql`{ ... }`, { alias: 'withCurrentUser' }),
  graphql(gql`{ ... }`, { alias: 'withList' }),
)(MyComponent); copyright www.7zhao.net 

看一下别名的效果, 我们实际的组件名称为 FeedbackList , 通过 graphql() 高阶组件包装后的组件名称为 Apollo(FeedbackList) , 如果组件不多的情况下, 我们很好分辨不同的组件, 如果一个单页应用中使用了大量的 graphql() 高阶组件, 这样的名字容易引其混乱, 因此我们通过 alias 能够避免名称上的混乱, 让组件更容易识别. 下面我们看一下代码: 内容来自www.7zhao.net

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { graphql, gql, withApollo, compose } from 'react-apollo'

// 查询文本
import QUERY_FEEDBACKS from './graphql/ListFeedback.graphql'
import SUBSCRIPTION_NEW_FEEDBACKS from './graphql/SubscribeAddFeedback.graphql'

// 反馈列表组件
class FeedbackList extends Component {
  // constructor(props) {
  //   super(props)
  // }
  componentWillMount() {
    this.props.subscribeToNewFeedback();
  }
  render() {
    if(this.props.data.loading == true) {
      return <div>Loading...</div>
    } else {
      return (
        <ul>{
          this.props.data.feedbacks.map((item, index) => {
            console.log(item.id)
            return (
              <div key={item.id}>{item.text}</div>
            )
          })
        }</ul>
      )
    }
  }
}
// 属性验证
FeedbackList.propTypes = {
  subscribeToNewFeedback: PropTypes.func.isRequired
}
// 高阶组件
export default graphql(QUERY_FEEDBACKS, {
  // name: 'FeedbackList',
  options: ({ params }) => ({
    variables: {
      key: 'value'
    },
  }),
  // 无别名时的效果
  // alias: 'FeedbackListWithData' 
})(FeedbackList); 内容来自www.7zhao.net 

无别名

copyright www.7zhao.net

本文来自去找www.7zhao.net

增加别名后 copyright www.7zhao.net

欢迎访问www.7zhao.net

代码

本文所描述的代码放在 上, 可以Clone下来进行学习和测试, 代码中的数据是通过一个内存数组存储的, 服务器重启后数据丢失. 如果需要持久化, 可以改为使用数据库. copyright www.7zhao.net

示例代码实现了GraphQL的订阅模式, 客户端通过 Websocket 建立到服务器的长连接. 可以一次作为「使用GraphQL实现即时聊天应用」的基础, 示例代码包含完整的服务器和客户端代码, 可通过下面两行命令启动服务器和客户端. 本文来自去找www.7zhao.net

# 启动GraphQL服务器 
# GraphQL服务器, 提供GraphQL查询接口: http://localhost:7001/api
# 订阅服务器, 订阅功能: http://localhost:7003/feedback

yarn server 

# 启动 webpack dev server , 提供Web界面: http://localhost:7001

yarn client 
欢迎访问www.7zhao.net

GraphiQL 查询工具, 可以通过 http://localhost:7001/graphiql 访问. 启动服务器和客户端后, 可以通过在 GraphiQL 工具中执行如下的查询看到效果: www.7zhao.net

查询

copyright www.7zhao.net

mutation AddFeedback($data: FeedbackInput!) {
  addFeedback(data: $data) {
    id
    text
  }
} 内容来自www.7zhao.net 

变量 www.7zhao.net

{
  "data": {
    "text": "我是一个粉刷匠, 粉刷本领强"
  }
} copyright www.7zhao.net 

这个连接是订阅 www.7zhao.net

本文来自去找www.7zhao.net

这个连接是添加一条反馈(Feedback)记录, 以及对应的变量. 执行此Mutation, 会在客户端和订阅窗口看到数据的实时更新.

去找(www.7zhao.net欢迎您

欢迎访问www.7zhao.net

参考资料

www.7zhao.net

去找(www.7zhao.net欢迎您

去找(www.7zhao.net欢迎您

copyright www.7zhao.net

欢迎访问www.7zhao.net


本文原文地址:https://segmentfault.com/a/1190000009586488

以上为GraphQL 入门: Apollo Client API 之 graphql 容器文章的全部内容,若您也有好的文章,欢迎与我们分享!

copyright www.7zhao.net

Copyright ©2008-2017去找网版权所有   皖ICP备12002049号-2 皖公网安备 34088102000435号   关于我们|联系我们| 免责声明|友情链接|网站地图|手机版