Обновите локальную конфигурацию, основанную на результате запроса в Reaction-Apollo - PullRequest
0 голосов
/ 23 ноября 2018

Используя apollo и реагировать, я хочу обновить свое локальное состояние apollo на основе результата (удаленного) запроса apollo.

Запрос имеет тип [String!]!, мое локальное состояние содержит {name}типа String.Я хочу присвоить локальное {имя} первому элементу, возвращенному запросом.

const App = compose(
    graphql(gql`{ name @client }`, { name: 'localData' }),
    graphql(gql`{ currencies { name } }`)
)(({ localData }) => <h1>{ localData.name }</h1>)

Я не хочу использовать componentWillReceiveProps (мутирует там локальное состояние, как только опоры приходят изудаленный запрос), так как это плохая практика.

Мне нужно использовать локальное состояние apollo, а не только состояние компонента, так как это значение будет использоваться другими компонентами.

Iпопытался использовать props конфиг graphql hoc, но он чувствует себя так же плохо, как componentWillReceiveProps, и привести к бесконечному циклу.

Есть идеи?

Соответствующие версии:

"apollo-boost": "^0.1.19",
"apollo-link-state": "^0.4.2",
"react-apollo": "^2.2.4",

Код

import React from 'react'
import ReactDOM from 'react-dom'
import ApolloClient from 'apollo-boost'
import gql from 'graphql-tag'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider, graphql, compose } from 'react-apollo'
import { ApolloLink } from 'apollo-link'
import { withClientState } from 'apollo-link-state'
import { HttpLink } from 'apollo-link-http'

const resolvers = {
    Mutation: {
        updateName: (ops, { name }, { cache }) => cache.writeData({ data: { name } })
    }
}
const typedefs = gql`
  type Query {
    name: String
  }
  type Mutation {
    updateName(name: String): String
  }
`
const defaults = { name: 'defaultName' }
const cache = new InMemoryCache()
const stateLink = withClientState({
    cache,
    defaults,
    resolvers
});
const apolloClient = new ApolloClient({
    uri: '/store/api/graphql',
    link: ApolloLink.from([stateLink, new HttpLink()]),
    cache,
    clientState: {
        defaults,
        resolvers,
        typedefs
    }
})

const App = compose(
    graphql(gql`{ name @client }`, { name: 'localData' }),
    graphql(gql`{ currencies { name id } }`)
)(({ localData }) => <h1>{ localData.name }</h1>)

ReactDOM.render(
    <ApolloProvider client={ apolloClient }>
        <App />
    </ApolloProvider>,
    document.getElementById('app')
)

1 Ответ

0 голосов
/ 23 ноября 2018

Я нашел решение, используя компонент Query вместо graphql hoc.Компонент Query имеет свойство onCompleted, где я могу передать функцию, которая обновляет локальное состояние:

const UPDATE_NAME = gql`mutation ($name: String) {
    updateName (name: $name) @client { name }
}`
const App = compose(
    withApollo,
    graphql(gql`{ name @client }`, { name: 'localData' })
)(({ client, localData }) => <Query
    query={ gql`{ currencies { name id } }` }
    onCompleted={ data =>
        client.mutate({
            mutation: UPDATE_NAME,
            variables: { name: data.currencies[0].name }
        })
    }>
    {
        () => <h1>Current: { localData.name }</h1>
    }
</Query>)

Я нахожу компонент Query менее элегантным, чем graphql hoc, но, по крайней мере, это решение.

...