2017-07-17 4 views
0

Ich habe gerade graphql auf meinem Server eingerichtet und wollte Apollo mit meinem Frontend verbinden.Map Query zu Requisiten mit Apollo.js in React

Ich war in der Lage, Apollo mit Redux (How to pass initial state to reducer) zu integrieren, aber jetzt den Status zu Requisiten über redux connect zuordnen möchten.

Meine aktuelle Heim-Komponente sieht wie folgt aus:

import React, { Component } from 'react' 
import { connect } from 'react-redux' 
import { graphql } from 'react-apollo'; 

import './Home.css' 

class Home extends Component { 

    render() { 
    return (
     <section className='home-container'> 
     <h1>Site Name</h1> 
     </section> 
    ) 
    } 
} 

const mapStateToProps = state => ({ 
    curPage: state.curPage 
}) 

export default connect(
    mapStateToProps, 
)(Home) 

ich im Wesentlichen mapStateToProps mit mapQueryToProps ersetzen wollen aber ich bin nicht sicher, wie das funktioniert.

Stellt dies eine Anfrage an meinen /graphql Endpunkt und ordnen Sie die Antwort auf curPage?

Wird dies vor dem ersten Rendern passieren? Wie in wird this.props.curPage innerhalb componentWillMount() verfügbar sein? (Ich brauche dies für seo Zwecke, um sicherzustellen, dass der gesamte Inhalt serverseitig gerendert wird).

Wo konfiguriere ich meinen graphql-Endpunkt? Ich sehe einige Beispiele, die es in ihrem Geschäft konfigurieren. Mein Speicher ist aufgeteilt in store.js und index.js leicht aber ist wie folgt:

// index.js

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { BrowserRouter } from 'react-router-dom'; 

import App from './containers/App/App'; 

import initialState from './initialState'; 
import configureStore from './store'; 

import { ApolloClient, ApolloProvider } from 'react-apollo'; 

const client = new ApolloClient(); 

// Let the reducers handle initial state 

initState() // eslint-disable-line 

// if we are in production mode, we get the initial state from the window object, otherwise, when we are in dev env we get it from a static file 
const preloadedState = window.__INITIAL_STATE__ === '{{__PRELOADEDSTATE__}}' ? initialState : window.__INITIAL_STATE__ 

const store = configureStore(preloadedState) 

ReactDOM.render(
    <ApolloProvider store={store} client={client}> 
    <BrowserRouter> 
     <App /> 
    </BrowserRouter> 
    </ApolloProvider>, 
    document.getElementById('root') 
) 

// store.js

import { createStore, applyMiddleware, compose } from 'redux' 
import { createLogger } from 'redux-logger' 
import reducers from './reducers' 
import { ApolloClient } from 'react-apollo'; 

const logger = createLogger() 
const client = new ApolloClient(); 

export default function configureStore(initialState = {}) { 

    // Create the store with two middlewares 
    const middlewares = [ 
    // sagaMiddleware 
    logger, 
    client.middleware() 
    ] 

    const enhancers = [ 
    applyMiddleware(...middlewares) 
    ] 

    const store = createStore(
    reducers, 
    initialState, 
    compose(...enhancers) 
) 

    // Extensions 
    store.asyncReducers = {} // Async reducer registry 

    return store 
} 

aktualisieren

Ich importiere jetzt meinen Client aus meinem Geschäft, so dass ich nur eine Instanz meines Clients habe. Ich verwende auch /graphql als meinen Endpunkt, so dass ich den Endpunkt nicht konfigurieren sollte.

// index.js

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { BrowserRouter } from 'react-router-dom'; 

import App from './containers/App/App'; 

import initialState from './initialState'; 
import {configureStore, client} from './store'; 

import { ApolloClient, ApolloProvider } from 'react-apollo'; 

initState() // eslint-disable-line 

// if we are in production mode, we get the initial state from the window object, otherwise, when we are in dev env we get it from a static file 
const preloadedState = window.__INITIAL_STATE__ === '{{__PRELOADEDSTATE__}}' ? initialState : window.__INITIAL_STATE__ 

const store = configureStore(preloadedState) 

ReactDOM.render(
    <ApolloProvider store={store} client={client}> 
    <BrowserRouter> 
     <App /> 
    </BrowserRouter> 
    </ApolloProvider>, 
    document.getElementById('root') 
) 

noch ein bisschen verwirrt über graphql(MY_QUERY, { props: mapQueryToProps })(Home)

Ich habe eine Abfrage curPage zu erhalten, die in graphiql funktioniert: (Ich vermute, MY_QUERY sollte dies gleich sein?)

query { 
    findResource(filter: {resource: "pages", slug: "about"}) { 
    id 
    title 
    slug 
    path 
    sections 
    } 
} 

und kehrt:

Würde das bedeuten, meine

const mapQueryToProps = ({data: { getPage: { page } }, ownProps}) => ({ curPage: page }) 

sollte wie folgt aussehen:

const mapQueryToProps = ({data: { findResource: { page } }, ownProps}) => ({ curPage: page }) 

Antwort

3

Paar Punkte:

Sie erstellen zwei Instanzen von ApolloClient - ein in index.js und eine in store.js - Sie könnten den Client an configureStore übergeben, und auf diese Weise verwenden Sie dieselbe Instanz.

Wenn sich Ihr graphQL-Endpunkt an einer anderen Stelle als /graphql befindet, müssen Sie eine benutzerdefinierte Netzwerkschnittstelle verwenden.Example from the docs:

import { ApolloClient, createNetworkInterface } from 'react-apollo'; 
const networkInterface = createNetworkInterface({ 
    uri: 'http://api.example.com/graphql' 
}); 
const client = new ApolloClient({ networkInterface }); 

Mit nur minimalem Setup werden die Daten aus der Abfrage wird nicht sofort verfügbar sein - die Komponente wird automatisch eingerichtet und rerender, sobald die Daten verfügbar sind. Jedoch, the documentation provides a couple of ways to get around that.

Soweit die Abfragedaten Requisiten zugeordnet werden, ist es wichtig zu beachten, dass Apollo connect nicht verwendet, sondern eine eigene HOC hat. Sie werden es in ähnlicher Weise verwenden:

graphql(MY_QUERY, { props: mapQueryToProps })(Home) 

Die Funktion, die Sie Requisiten zuweisen wird ein einzelnes Objekt übergeben werden, die zwei Eigenschaften, data und ownProps. Daten enthalten das Ergebnis Ihrer Abfrage und ownProps verweist auf vorhandene Requisiten für die Komponente. Also Ihr mapQueryToProps könnte etwas wie folgt aussehen:

const mapQueryToProps = ({data: { getPage: { page } }, ownProps}) => 
    ({ curPage: page }) 

Sie auch props ganz Angabe weglassen kann, und Sie werden einfach die ganze data Objekt als Stütze erhalten. Das obige ist nur eine Möglichkeit, das zu verfeinern, was der Komponente als Requisite zugewiesen wird.

Wenn es noch Teile Ihres Bundesstaates gibt, für die Sie redux weiter verwenden möchten, finden Sie in der Dokumentation einen Abschnitt zur Integration von redux und Apollo. Es ist ziemlich sauber, wenn Sie komponieren oder recompose verwenden.

Apollos Dokumentation für reagieren ist ziemlich klar und auf den Punkt. Wenn Sie dies noch nicht getan haben, möchten Sie vielleicht nur die Abschnitte Setup and options und Usage durchgehen und vielleicht sogar durch alle anwendbaren Recipes, bevor Sie fortfahren.

EDIT: Die Abfrage, die Sie an die HOC übergeben, muss eine Zeichenfolge sein. Am einfachsten ist es, das gql-Tag zu importieren und zu verwenden. Basierend auf der Abfrage, die Sie zur Verfügung gestellt haben, würde es wie folgt aussehen:

const MY_QUERY = gql` 
    query { 
    findResource(filter: {resource: "pages", slug: "about"}) { 
     id 
     title 
     slug 
     path 
     sections 
    } 
    }` 
+0

Ok, also habe ich die Änderungen an den Client gemäß Ihrer Empfehlung vorgenommen. Ich habe meinen ursprünglichen Post mit der Art aktualisiert, wie ich das gemacht habe. Zweitens bin ich immer noch ein wenig unsicher, wie manQueryToProps abbildet. Ich habe meinen ursprünglichen Beitrag mit einem anderen Beispiel aktualisiert. Bin ich auf dem richtigen Weg? Ich habe die von Ihnen vorgeschlagene Dokumentation ebenfalls gelesen. – Stretch0

+1

Siehe meine Bearbeitung für die Übergabe der Abfrage. Sie können mehr [hier] lesen (http://dev.apollodata.com/react/queries.html#basics). Soweit die mapQueryToProps ... In meinem Beispiel habe ich nur geschätzt, was Ihre Datenstruktur wäre; Sehen Sie sich an, was die Abfrage zurückgibt - das ist das Datenobjekt, mit dem Sie in mapQueryToProps arbeiten. Ich nehme an, Sie brauchen das erste Objekt innerhalb des Array, das zurückgegeben wird, so dass Sie einfach etwas tun könnten: ({Daten}) => ({curPage: data.findResource [0]}). –

+0

Oder mach dir keine Sorgen über die Einstellung der Requisiten für einen einfachen Fall wie diesen. Tun Sie einfach 'graphql (MY_QUERY) (Home)' und dann können Sie mit 'props.data' auf die Daten innerhalb Ihrer Komponente zugreifen. Könnte weniger Kopfschmerzen haben. –

Verwandte Themen