声明: 转载请注明出处
1.简介
react-apollo是Apollo数据栈在React环境的集成包之一,要在React里使用Apollo数据栈前端至少需要三个包:apollo-client、graphql-tag和react-apollo,apollo-client用于连接到Apollo后端,graphql-tag用于编写GraphQL查询,react-apollo用于执行GraphQL查询并将结果传给React的展示组件。
2.创建client
//默认client会将url设为 `/graphql`
import { ApolloClient } from 'react-apollo';
const client = new ApolloClient();
//当你需要改变graphql server的url的时候,需使用networkInterface
import { ApolloClient, createNetworkInterface } from 'react-apollo';
const networkInterface = createNetworkInterface({
uri: 'http://api.example.com/graphql'
});
const client = new ApolloClient({
networkInterface: networkInterface
);
3.创建provider,用于连接client和component
import { ApolloClient, ApolloProvider } from 'react-apollo';
const client = new ApolloClient();
ReactDOM.render(
<ApolloProvider client={client}>
<MyAppComponent />
</ApolloProvider>,
document.getElementById('root')
)
4.使用
(1)Queries
1.1基本查询
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
class Profile extends Component { ... }
// We use the gql tag to parse our query string into a query document
const CurrentUserForLayout = gql`
query CurrentUserForLayout {
currentUser {
login
avatar_url
}
}
`;
const ProfileWithData = graphql(CurrentUserForLayout)(Profile)
1.2 参数查询
const CurrentUserForLayout = gql`
query CurrentUserForLayout($avatarSize: Int!) {
currentUser {
login
avatar_url(avatarSize: $avatarSize)
}
}
`;
const ProfileWithData = graphql(CurrentUserForLayout, {
options: { variables: { avatarSize: 100 } },
})(Profile);
(2)Mutation
2.1基本修改
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { gql, graphql } from 'react-apollo';
class NewEntry extends Component { ... }
const submitRepository = gql`
mutation submitRepository {
submitRepository(repoFullName: "apollographql/apollo-client") {
createdAt
}
}
`;
const NewEntryWithData = graphql(submitRepository)(NewEntry);
2.2传参修改
//被包裹的组件会传递一个mutate作为props传递过去,可以用来传递mutation操作参数,如:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { gql, graphql } from 'react-apollo';
class NewEntry extends Component {
onClick() {
this.props.mutate({
variables: { repoFullName: 'apollographql/apollo-client' }
})
.then(({ data }) => {
console.log('got data', data);
}).catch((error) => {
console.log('there was an error sending the query', error);
});
}
render() {
return <div onClick={this.onClick.bind(this)}>Click me</div>;
}
}
const submitRepository = gql`
mutation submitRepository($repoFullName: String!) {
submitRepository(repoFullName: $repoFullName) {
createdAt
}
}
`;
const NewEntryWithData = graphql(submitRepository)(NewEntry);
//也可以对mutate根据需要进行自己的函数封装
const NewEntryWithData = graphql(submitRepository, {
props: ({ mutate }) => ({
submit: (repoFullName) => mutate({ variables: { repoFullName } }),
}),
})(NewEntry);
//这时在component中可直接调用submit
const NewEntry = ({ submit }) => (
<div onClick={() => submit('apollographql/apollo-client')}>
Click me
</div>
);
(3)使用compose
很多时候我们的页面中存在多个queries和mutation操作,这时候我们需要使用compose来进行组合
import { compose } from 'react-apollo';
const ComponentWithMutations = compose(
graphql(submitNewUser, { name: 'newUserMutation' }),
graphql(submitRepository, { name: 'newRepositoryMutation' })
)(Component);
5.执行Mutation后进行状态更新
5.1 refetchQueries
refetchQueries是用来更新缓存的简单方法,当你在执行完一次mutation操作后,可能会有一个或多个状态被影响,这时可以指定一个或多个需要执行的queries来刷新这部分store
mutate({
//... insert comment mutation
refetchQueries: [{
query: gql`
query updateCache($repoName: String!) {
entry(repoFullName: $repoName) {
id
comments {
postedBy {
login
html_url
}
createdAt
content
}
}
}
`,
variables: { repoFullName: 'apollographql/apollo-client' },
}],
})
5.2 update
import CommentAppQuery from '../queries/CommentAppQuery';
const SUBMIT_COMMENT_MUTATION = gql`
mutation submitComment($repoFullName: String!, $commentContent: String!) {
submitComment(repoFullName: $repoFullName, commentContent: $commentContent) {
postedBy {
login
html_url
}
createdAt
content
}
}
`;
const CommentsPageWithMutations = graphql(SUBMIT_COMMENT_MUTATION, {
props({ ownProps, mutate }) {
return {
submit({ repoFullName, commentContent }) {
return mutate({
variables: { repoFullName, commentContent },
update: (store, { data: { submitComment } }) => {
// 从CommentAppQuery 中读取出查询得到的缓存数据
const data = store.readQuery({ query: CommentAppQuery });
// 将mutation的结果放入查询得到的数据中
data.comments.push(submitComment);
// 将数据重新写入缓存中,实现数据的更新
store.writeQuery({ query: CommentAppQuery, data });
},
});
},
};
},
})(CommentsPage);