📜 ⬆️ ⬇️

Apollo graphql client - developing applications on react.js without redux

Apollo graphql client provides a convenient, concise way to work with data in the react applications. In most cases, everything that we used to do with redux is much easier to do with the Apollo graphql client. What I would like to talk about in this article is that a bunch of react + apollo client + graphql significantly (by an order of magnitude) simplifies the development of applications for react.

For work, we will use the graphql test server at . graphql out of the box offers, among other things, a console for querying, and integrated documentation in it. I propose to open this panel. In the left panel, you can enter a request, the answer will be displayed in the right one. Try typing the simplest query:

query { allUsers { id name } } 

allUsers is the name of the request, and inside the curly brackets are the names of the fields to be returned. More complex queries may contain a list of parameters and contain fields of nested objects:

 query { allPosts(orderBy: updatedAt_DESC, first: 7){ id title user { id name } } } 

In this case, the orderBy and limit parameters should not be interpreted as in SQL. These are just parameter names that, by themselves, do not do a sorting or restriction selection without implementation.
')
Other parameters and output fields of these requests can be viewed from the console interface.

As a basis for the application, we take the react-create-app. Additionally, install apollo-client and react-router-dom:

 npm install apollo-boost react-apollo graphql-tag graphql --save npm install react-router-dom --save 

Let's change the main component of the App.js application:

 import React from 'react'; import { Route, Switch, BrowserRouter } from 'react-router-dom'; import { ApolloProvider } from 'react-apollo'; import ApolloClient from 'apollo-boost'; import Layout from './Layout'; import AllUsers from './AllUsers'; import TopPosts from './TopPosts'; import NewPost from './NewPost'; const client = new ApolloClient({ uri: 'https://api.graph.cool/simple/v1/ciyz901en4j590185wkmexyex', }); const App = () => ( <ApolloProvider client={client}> <BrowserRouter> <Layout> <Switch> <Route exact path='/' component={ AllUsers } /> <Route exact path='/posts' component={ TopPosts } /> <Route exact path='/user/:userId' component={ NewPost } /> </Switch> </Layout> </BrowserRouter> </ApolloProvider> ); export default App; 

AploolProvider and ApolloClient are all that is needed in order to use graphql in all components.

The easiest way is to transfer data to the component using the Query tag. Let's display the list of users in the component (we have already tried the request in the console before):

 import React from 'react'; import { Link } from 'react-router-dom' import { Query } from "react-apollo"; import gql from "graphql-tag"; import TopPosts from './TopPosts'; const AllUsers = () => ( <Query query={gql` query { allUsers { id name } } `} > {({ loading, error, data }) => { for (let key in arguments[0]) console.log(key, arguments[0][key]); console.log('data', data) if (loading) return <p>Loading...</p>; if (error) return <p>Error :(</p>; return ( <ul key='allUsers'> {data.allUsers.map(({ id, name }) => ( <li key={id}><Link to={`/user/${id}`}>{name ? name : 'incognoito'}</Link></li> ))} </ul> ); }} </Query> ); export default AllUsers 

Mutation is used to add or change state on the server:

 import React from 'react'; import { Link } from 'react-router-dom' import { Mutation } from 'react-apollo'; import gql from 'graphql-tag'; const NewPost = (props) => ( <Mutation mutation={gql` mutation createPost($text: String!, $title: String!, $userId: ID!){ createPost(text: $text, title: $title, userId: $userId) { id } } `} > {(createPost, { loading, error, data }) => { if (loading) return <p>Loading...</p>; if (error) return <p>Error :(</p>; let userId, title, text return ( <form onSubmit={e => { e.preventDefault(); createPost({ variables: { userId: userId.value , title: title.value , text: text.value , }}); }}> <input type='hidden' value={ props.match.params.userId } ref={ node => userId = node } /> <input type='text' ref={ node => title = node } /> <textarea ref={ node => text = node } /> <button type='submit' /> </form> ); }} </Mutation> ); export default NewPost; 


When I got acquainted with examples of components of the react using apollo graphql client, I didn’t feel very comfortable. And the thing is that a web application developer thinks more imperatively than declaratively. We want action. Set Filter, Save Record, etc. And when we turn to the fact that we do not need to think about how data is loaded from the server, instead of adopting such an approach and using its benefits, we reflect on how we will monitor the store.

I supplement the text with another example in which the parameter received from the enclosing component (route) is used in the graphql query.

 import React from 'react'; import { Link } from 'react-router-dom' import { Query } from 'react-apollo'; import gql from 'graphql-tag'; const Post = (props) => ( <Query query={gql` query { Post(id: "${props.match.params.postId}") { id title text } } `} fetchPolicy='network-only' > {({ loading, error, data }) => { if (loading) return <p>Loading...</p>; if (error) return <p>Error :(</p>; return ( <ul key='topPosts'> <li>{data.Post.id}</li> <li>{data.Post.title}</li> <li>{data.Post.text}</li> </ul> ); }} </Query> ); export default Post; 


Source code

The Apollo client also works in server rendering and universal applications. Preloading of data for server rendering (including all nested components) is implemented out of the box. The paradox is that combining several technologies that are often criticized for their complexity have resulted in a significant simplification of the application.

apapacy@gmail.com
May 11, 2018.

Source: https://habr.com/ru/post/358292/


All Articles