GraphQL 进阶: Apollo Client 之 GraphQL Subscription 和 graph
概述下面是一个视频和一个GIF动画,感受一下基于Websocket,通过GraphQL实现的即时聊天应用是个什么鬼. 视频连接: https://v.qq.com/x/page/x0508... GIF动画
graphql 容器的基本形态如下: # 导入 graphql 函数 import { graphql } from 'react-apollo'; # 函数签名,参数分别为GraphQL查询(通过gql 模板标签进行构造,一个可选的配置对象,以及一个被包装的React组件) graphql(query,[config])(component)
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); 也可以定义中间函数 # 中间函数 const withTodoAppQuery = graphql(gql`query { ... }`); # 传入React组件给这个中间函数 const TodoAppWithData = withTodoAppQuery(TodoApp); # 导出这个组件 export default TodoAppWithData;
@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> ); } }
通过 配置对象config.options
options: ({ params }) => ({ variables: { text: '我是一个粉刷匠,粉刷本领强4' },}), 纯对象很简单,形式为: const config = { name: 'getTodos' }
export default graphql(TODO_QUERY,{ options: (props) => ({ }),})(MyComponent); config.props该属性用于定义一个映射函数. 传入组件自身的属性,和通过
config.name
我们方位GraphQL查询结果的数据通常是通过 export default compose( graphql(gql`mutation (...) { ... }`,{ name: 'createTodo' }),graphql(gql`mutation (...) { ... }`,{ name: 'updateTodo' }),{ name: 'deleteTodo' }),)(MyComponent); function MyComponent(props) { console.log(props.createTodo); console.log(props.updateTodo); console.log(props.deleteTodo); return null; 这样,我们就可以通过 config.withRef
# 创建一个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(); }} /> ); } } config.alias
export default compose( graphql(gql`{ ... }`,{ alias: 'withCurrentUser' }),graphql(gql`{ ... }`,{ alias: 'withList' }),)(MyComponent); 看一下别名的效果,我们实际的组件名称为 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); 无别名 增加别名后 代码本文所描述的代码放在Github上,可以Clone下来进行学习和测试,代码中的数据是通过一个内存数组存储的,服务器重启后数据丢失. 如果需要持久化,可以改为使用数据库. 示例代码实现了GraphQL的订阅模式,客户端通过 Websocket 建立到服务器的长连接. 可以一次作为「使用GraphQL实现即时聊天应用」的基础,示例代码包含完整的服务器和客户端代码,可通过下面两行命令启动服务器和客户端. # 启动GraphQL服务器 # GraphQL服务器,提供GraphQL查询接口: http://localhost:7001/api # 订阅服务器,订阅功能: http://localhost:7003/feedback yarn server # 启动 webpack dev server,提供Web界面: http://localhost:7001 yarn client GraphiQL 查询工具,可以通过 查询 mutation AddFeedback($data: FeedbackInput!) { addFeedback(data: $data) { id text } } 变量 { "data": { "text": "我是一个粉刷匠,粉刷本领强" } } 这个连接是订阅 http://localhost:7001/graphiq... 这个连接是添加一条反馈(Feedback)记录,以及对应的变量. 执行此Mutation,会在客户端和订阅窗口看到数据的实时更新. http://localhost:7001/graphiq... 参考资料http://dev.apollodata.com/rea... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |