React和Apollo结合前后端通信总结
React和Apollo结合前后端通信总结
react官方文档:https://react.docschina.org
Apollo官方文档:https://www.apollographql.com/docs/react
antd官方文档:https://ant.design/index-cn
MATERIAL-UI:https://material-ui.com/zh
环境准备
使用create-react-app脚手架创建react项目
1
create-react-app app
安装对于Apollo和graphql的依赖
1
npm install @apollo/client graphql
安装支持Apollo上传文件的依赖 https://github.com/jaydenseric/apollo-upload-client
1
npm install apollo-upload-client
配置ApolloClient
App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
import { Route, BrowserRouter as Router } from "react-router-dom";
import { createUploadLink } from "apollo-upload-client";
const client = new ApolloClient({
link: createUploadLink({
uri: "http://xxxxxxxx/graphql/",
}),
cache: new InMemoryCache(),
});
function App() {
return (
<Router>
<Header />
<ApolloProvider client={client}>
<Route path="/" component={} exact></Route>
<Route path="/afp" component={} exact></Route>
</ApolloProvider>
</Router>
);
}
export default App;以上完成了react和Apollo的结合,并支持上传文件的操作,在路由中的组件均可使用Apollo提供的方法进行请求和发送数据。
使用Apollo进行数据交互
以下内容均建立在函数组件的基础上。
useQuery1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import { gql, useQuery } from '@apollo/client';
const GET_ALL_PRODUCTS = gql`
query {
products {
id
name
appType
}
}
`;
const Index = () => {
const { loading, error,data } = useQuery(GET_ALL_PRODUCTS);
if (data)
return (
<div>
{data.products.map((item) => {
return (
<li>{item.name}</li>
);
})}
</div>
);
return null;
};
export default Index;当该组件渲染时,会自动的执行useQuery方法并将请求得到的数据赋值给data。在html的部分可以用data渲染UI。
useLazyQuery1
2
3import { useLazyQuery } from "@apollo/client";
import { GET_JSON_RESULT } from "../graphql/queries";
const [getJSON, { data }] = useLazyQuery(GET_JSON_RESULT)使用该方法,可以返回一个函数(如上面的getJSON,方法名自己取的(下同))和一个对象。你可以在一些事件中按需要去执行查询(比如,点击按钮执行查询)。只需要在事件中调用返回的函数即可(如上面的getJSON)。但是,调用函数并不返回一个promise,所以你不能通过.then()得到返回的数据。个人推测执行查询是一个异步操作,如果此时,你打印data,得到的数据会是undefined,当查询结束后data才是查询得到的结果。那么如何能够拿到返回的数据并进行处理呢?
可以使用如下方式:1
2
3
4
5
6const [getJSON, { data }] = useLazyQuery(GET_JSON_RESULT, {
onCompleted: (data) => {
// onCompleted是内置回调,
//形参data即为后台的响应内容,可以在此处进行处理。
},
});useMutation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34import { gql,useMutation} from "@apollo/client";
const CREATE_CHECKOUT = gql`
mutation(
$product: Int!
$drawValue: String
$inputValue: String
$attr: [String]
$file: Upload
) {
CheckoutCreate(
checkout: {
product: $product
drawValue: $drawValue
inputValue: $inputValue
attr: $attr
uploadFile: $file
}
) {
ok
token
}
}
`;
const [submitCheckout] = useMutation(CREATE_CHECKOUT);
const submit=()=>{
submitCheckout({
variables: { product: 2,... },//传入变量
}).then((res)=>{
console.log(res)
})
return (
<button onClick={()=>{submit()}}>submit</button>
)
}使用useMutation返回一个方法(如上面的submitCheckout),可以在事件中调用,比如点击按钮提交订单信息,同时返回一个promise,因此我们可以通过.then()的方式拿到后台的数据。
以上三个方法能够完成获取和提交数据了,如果需要更加详细的教程:
Query: https://www.apollographql.com/docs/react/data/queries/
Mutation: https://www.apollographql.com/docs/react/data/mutations/Apollo缓存
Apollo带有缓存机制,同一个请求,如果之前已经缓存了则不会发起请求,而是从缓存中取数据。所以,在轮询查询订单状态的时候应该设置以下缓存规则,即不使用缓存。如下:
1
2
3const [getJSON, { data }] = useLazyQuery(GET_JSON_RESULT, {
fetchPolicy: "no-cache",
})文档地址:https://www.apollographql.com/docs/react/data/queries/#supported-fetch-policies