Како користити ГрапхКЛ у својој апликацији Редук

Преузимање и управљање подацима у Редук-у захтева превише рада. Како истиче Сашко Стубаило:

Нажалост, обрасци за асинхроно учитавање података сервера у апликацији Редук нису толико добро успостављени и често укључују употребу спољних помоћних библиотека, попут редук-сага. Морате да напишете прилагођени код да бисте позвали крајње тачке сервера, протумачили податке, нормализовали их и убацили у складиште - све уз истовремено праћење различитих грешака и стања учитавања.

На крају овог водича научићете како да решите овај проблем тако што ћете дозволити Аполло Цлиенту да преузима и управља подацима за вас. Више нећете морати писати диспечере, редукторе и нормализаторе вишеструких акција да бисте преузели и синхронизовали податке између вашег предњег и задњег дела.

Пре него што започнете с упутством, уверите се да:

  • Знате основе ГрапхКЛ упита - ако сте потпуно нови у ГрапхКЛ-у, требали бисте се вратити након што обавите овај водич.
  • Имате искуства у раду са Реацт / Редук-ом - ако не, требало би да се вратите након реализације туторијала за реакције и редук-а.

У овом упутству ћемо заједно проћи кроз 6 одељака.

  1. Подешавање окружења сервера (брзо)
  2. Постављање апликације редук котла
  3. Додавање ГрапхКЛ клијента (Аполло клијент)
  4. Преузимање података помоћу ГрапхКЛ упита
  5. Преузимање још више података
  6. Следећи кораци

1. Постављање серверског окружења

Прво, потребан нам је ГрапхКЛ сервер. Најлакши начин да имате покренут сервер је довршавање овог сјајног водича.

Ако се осећате лено, можете само да клонирате мој репо, што је готово исти сервер који бисте добили да сте туториал урадили сами. Сервер подржава ГрапхКЛ упите за преузимање података из СКЛите ДБ-а.

Хајде да га покренемо и видимо да ли ради исправно:

$ git clone //github.com/woniesong92/apollo-starter-kit$ cd apollo-starter-kit$ npm install$ npm start

Сервер треба да ради на // лоцалхост: 8080 / грапхкл. Идите на ту страницу и погледајте да ли добијате радни ГрапхиКЛ интерфејс са резултатима попут овог:

ГрапхиКЛ вам омогућава да тестирате различите упите и одмах видите какав одговор добијате од сервера. Ако не желимо презиме аутора и поруку колачића судбине у одговору, можемо ажурирати упит као у наставку:

И управо тако волимо. Потврдили смо да наш сервер ради добро и да даје добре одговоре, па кренимо у изградњу клијента.

2. Постављање апликације редук котла

Ради једноставности, користићемо редуксни шаблон како бисмо могли бесплатно добити све поставке (нпр. Бабел, вебпацк, ЦСС, итд.). Свиђа ми се овај пример, јер је његово постављање лако пратити и само је на страни клијента - што га чини савршеним за овај водич.

$ git clone //github.com/woniesong92/react-redux-starter-kit.git$ cd react-redux-starter-kit$ npm install$ npm start

Идемо до // лоцалхост: 3000 / да видимо да ли је клијентски сервер покренут.

То, бре! Клијент ради. Време је да започнемо са додавањем ГрапхКЛ клијента. Поново, наш циљ је да лако дохватимо податке са сервера и прикажемо их на одредишној страници (ХомеВиев) без много напора помоћу ГрапхКЛ упита.

3. Додавање ГрапхКЛ клијента (Аполло клијент)

Инсталирајте пакете аполло-цлиент, респонсе-аполло и грапхкл-таг.

$ npm install apollo-client react-apollo graphql-tag --save

Затим отворите датотеку срц / цонтаинер / АппЦонтаинер.јс, корен наше Редук апликације. Овде преносимо редук продавницу на подређене компоненте, користећи добављача из респонсе-редук.

import React, { PropTypes } from 'react'import { Router } from 'react-router'import { Provider } from 'react-redux'
class AppContainer extends React.Component { static propTypes = { history: PropTypes.object.isRequired, routes: PropTypes.object.isRequired, routerKey: PropTypes.number, store: PropTypes.object.isRequired }
render () { const { history, routes, routerKey, store } = this.props
return ( ) }}
export default AppContainer

Морамо иницијализовати АполлоЦлиент и заменити добављача из респонсе-редук са АполлоПровидер из респонсе-аполло.

import React, { Component, PropTypes } from 'react'import { Router } from 'react-router'import ApolloClient, { createNetworkInterface, addTypename } from 'apollo-client'import { ApolloProvider } from 'react-apollo'
const client = new ApolloClient({ networkInterface: createNetworkInterface('//localhost:8080/graphql'), queryTransformer: addTypename,})
class AppContainer extends Component { static propTypes = { history: PropTypes.object.isRequired, routes: PropTypes.object.isRequired, store: PropTypes.object.isRequired }
render () { const { history, routes } = this.props
return ( ) }}
export default AppContainer

То је то! Управо смо додали ГрапхКЛ клијента у обичну Редук апликацију тако лако.

Идемо напред и испробајмо наш први ГрапхКЛ упит.

4. Преузимање података помоћу ГрапхКЛ упита

Отворите срц / виевс / ХомеВиев.јс

import React from 'react'import { connect } from 'react-redux'import { bindActionCreators } from 'redux'
export class HomeView extends React.Component { constructor(props) { super(props) }
render () { return ( 

Hello World

) }}
// This is where you usually retrieve the data stored in the redux store (e.g posts: state.posts.data)const mapStateToProps = (state, { params }) => ({
})
// This is where you usually bind dispatch to actions that are used to request data from the backend. You will call the dispatcher in componentDidMount.const mapDispatchToProps = (dispatch) => { const actions = {}
 return { actions: bindActionCreators(actions, dispatch) }}
export default connect( mapStateToProps, mapDispatchToProps)(HomeView)

ХомеВиев је конвенционални Редук контејнер (паметна компонента). Да бисмо користили ГрапхКЛ упите уместо диспечера акција за дохватање података, направићемо неке промене заједно.

  1. У потпуности уклоните мапДиспатцхТоПропс () и мапСтатеТоПропс ().
import React from 'react'import { connect } from 'react-redux'import { bindActionCreators } from 'redux'
export class HomeView extends React.Component { constructor(props) { super(props) }
 render () { return ( 

Hello World

) }}
export default connect({
})(HomeView)

2. Додајте мапКуериесТоПропс () и дефинишите ГрапхКЛ упит који ће дохватити податке о аутору. Приметите како је ово потпуно исти упит који смо тестирали на почетку користећи ГрапхИКЛ интерфејс на серверу.

import React from 'react'import { connect } from 'react-redux'import { bindActionCreators } from 'redux'
export class HomeView extends React.Component { constructor(props) { super(props) }
 render () { return ( 

Hello World

) }}
// NOTE: This will be automatically fired when the component is rendered, sending this exact GraphQL query to the backend.const mapQueriesToProps = ({ ownProps, state }) => { return { data: { query: gql` query { author(firstName:"Edmond", lastName: "Jones"){ firstName posts { title } } } ` } }}
export default connect({
})(HomeView)

3. Замените везу из респонсе-редук са цоннецт из респонсе-аполло и проследите мапКуериесТоПропс као аргумент. Једном када се мапКуериесТоПропс повеже са АполлоЦлиент, упит ће аутоматски дохватити податке са позадине када се прикаже ХомеВиев и проследити податке кроз реквизите.

import React from 'react'import { connect } from 'react-apollo' // NOTE: different connect!import gql from 'graphql-tag' // NOTE: lets us define GraphQL queries in a template language
export class HomeView extends React.Component { constructor(props) { super(props) }
render () { return ( 

Hello World

) }}
const mapQueriesToProps = ({ ownProps, state }) => { return { data: { query: gql` query { author(firstName:"Edmond", lastName: "Jones"){ firstName posts { title } } } ` } }}
export default connect({ mapQueriesToProps})(HomeView)

4. Приказати податке који су прослеђени из реквизита:

import React from 'react'import { connect } from 'react-apollo' // NOTE: different connect!import gql from 'graphql-tag' // NOTE: lets us define GraphQL queries in a template language
export class HomeView extends React.Component { constructor(props) { super(props) }
 render () { const author = this.props.data.author if (!author) { return 

Loading

}
 return ( 

{author.firstName}'s posts

{author.posts && author.posts.map((post, idx) => (
  • {post.title}
  • ))} ) }}
    const mapQueriesToProps = ({ ownProps, state }) => { return { data: { query: gql` query { author(firstName:"Edmond", lastName: "Jones"){ firstName posts { title } } } ` } }}
    export default connect({ mapQueriesToProps})(HomeView)

    If all went well, your rendered HomeView should look like below:

    To fetch and render the data we wanted, we didn’t have to write any action dispatcher, reducer, or normalizer. All we had to do on the client was to write a single GraphQL query!

    We successfully achieved our initial goal. But that query was quite simple. What if we wanted to display all authors instead of just one author?

    5. Fetching even more data

    In order to fetch and display all authors, we have to update our GraphQL query and render method:

    import React from 'react'import { connect } from 'react-apollo' // NOTE: different connect!import gql from 'graphql-tag' // NOTE: lets us define GraphQL queries in a template language
    export class HomeView extends React.Component { constructor(props) { super(props) }
    render () { const authors = this.props.data.authors if (!authors) { return 

    Loading

    }
     return ( {authors.map((author, idx) => ( 

    {author.firstName}'s posts

    {author.posts && author.posts.map((post, idx) => (
  • {post.title}
  • ))} ))} ) }}
    const mapQueriesToProps = ({ ownProps, state }) => { return { data: { query: gql` query { authors { firstName posts { title } } } ` } }}
    export default connect({ mapQueriesToProps})(HomeView)

    However, once you refresh your browser HomeView page, you will notice that you have an error in your console:

    ApolloError {graphQLErrors: Array[1], networkError: undefined, message: “GraphQL error: Cannot query field “authors” on type “Query”. Did you mean “author”?”}

    Ah, right! In our GraphQL server, we didn’t really define how to fetch authors.

    Let’s go back to our server and see what we have. Open the file apollo-starter-kit/data/resolvers.js

    import { Author, FortuneCookie } from './connectors';
    const resolvers = { Query: { author(_, args) { return Author.find({ where: args }); }, getFortuneCookie() { return FortuneCookie.getOne() } }, Author: { posts(author) { return author.getPosts(); }, }, Post: { author(post) { return post.getAuthor(); }, },};
    export default resolvers;

    Looking at Query resolver, we notice that our GraphQL server only understands author and getFortuneCookie queries now. We should teach it how to “resolve” the query authors.

    import { Author, FortuneCookie } from './connectors';
    const resolvers = { Query: { author(_, args) { return Author.find({ where: args }); }, getFortuneCookie() { return FortuneCookie.getOne() }, authors() { // the query "authors" means returning all authors! return Author.findAll({}) } }, ...};
    export default resolvers;

    We are not done yet. Open the file apollo-starter-kit/data/schema.js

    const typeDefinitions = `...
    type Query { author(firstName: String, lastName: String): Author getFortuneCookie: String}schema { query: Query}`;
    export default [typeDefinitions];

    This Schema makes it clear what kind of queries the server should expect. It doesn’t expect authors query yet so let’s update it.

    const typeDefinitions = `...
    type Query { author(firstName: String, lastName: String): Author getFortuneCookie: String, authors: [Author] // 'authors' query should return an array of // Author}schema { query: Query}`;
    export default [typeDefinitions];

    Now that our GraphQL server knows what the “authors” query means, let’s go back to our client. We already updated our query so we don’t have to touch anything.

    export class HomeView extends React.Component {
    ...
    const mapQueriesToProps = ({ ownProps, state }) => { return { data: { query: gql` query { authors { firstName posts { title } } } ` } }}
    export default connect({ mapQueriesToProps})(HomeView)

    Овим упитом очекујемо да сви аутори добију имена и постове. Само напред и освежите прегледач да бисте видели да ли добијамо праве податке.

    Ако је све прошло у реду, ваша страница ХомеВиев ће изгледати као горе.

    6. Следећи кораци

    Овај туториал истражује само мали део ГрапхКЛ-а и изоставља мноштво концепата као што су ажурирање података на серверу или коришћење другог позадинског сервера (нпр. Раилс).

    Док радим на томе да их представим у следећим водичима, можете прочитати Сашков пост или Аполло Цлиент Доц да бисте боље разумели шта се дешава испод хаубе (на пример, шта се десило када смо Провидер заменили АполлоПровидер?).

    Копање по изворном коду ГитХунт-а, пуне апликације Аполло Цлиент и Сервер примера, такође се чини одличним начином учења.

    Ако имате повратне информације, оставите их у коментару. Трудићу се да будем од помоћи :)