2017-06-18 47 views
8

我是全新的react-apollo我很困惑,如何從服務器端重新水化狀態到客戶端和我的應用程序工作,但問題是它不是從Apollo使用預加載狀態後組件呈現它調用API再次。如何從服務器端補充我的阿波羅狀態?

嚴重的Redux集成使複雜只有阿波羅狀態是渲染不是自定義的redux狀態,這是問題here.But我不知道如何集成。

Server.js

const HTML = ({ html,state}) => (

    <html lang="en" prefix="og: http://ogp.me/ns#"> 
    <head> 
     <meta charSet="utf-8" /> 
     <meta httpEquiv="X-UA-Compatible" content="IE=edge" /> 
     <meta httpEquiv="Content-Language" content="en" /> 
     <meta name="viewport" content="width=device-width, initial-scale=1" /> 

    </head> 
    <body> 
    <div 
     id="app" 
     dangerouslySetInnerHTML={{ __html: html }} /> 
    <script dangerouslySetInnerHTML={{ 
     __html: `window.__STATE__=${JSON.stringify(state)};`, 
    }} /> 

    <script src="/static/app.js" /> 

    </body> 
    </html> 
); 

app.get('/*',(req,res) => { 
    const routeContext = {}; 
    const client = serverClient(); 

    const components = (
     <StaticRouter location={req.url} context={routeContext}> 
      <ApolloProvider store={store} client={client}> 
       <WApp /> 
      </ApolloProvider> 
     </StaticRouter> 
    ); 

    getDataFromTree(components).then(() => { 
     const html = ReactDOMServer.renderToString(components); 
     const initialState = {apollo: client.getInitialState()} 


     res.send(`<!DOCTYPE html>\n${ReactDOMServer.renderToStaticMarkup(
      <HTML 
       html={html} 
       state={initialState} 
       />, 
     )}`) 


    }) 


}) 

apolloClient.js

import ApolloClient, { 
    createNetworkInterface, 
    addTypeName, 
} from 'apollo-client'; 
const isProduction = process.env.NODE_ENV !== 'development'; 
const testUrl = 'http://localhost:3000/api'; 

// const url = isProduction ? productionUrl : testUrl; 
const url = testUrl; 





const client = new ApolloClient({ 

    networkInterface: createNetworkInterface({uri:testUrl}), 
    dataIdFromObject:({id}) => id, 
    reduxRootKey:state => state.apollo, 
    initialState: (typeof window !=='undefined')? window.__STATE__:{} 






}); 







export default client; 

store.js

import { createStore, compose, applyMiddleware } from 'redux'; 
import { syncHistoryWithStore } from 'react-router-redux'; 
import thunk from 'redux-thunk'; 
import {createLogger} from 'redux-logger'; 


import client from '../apolloClient'; 
import rootReducer from '../Reducers' 

//All Reducer 
import {initialState as allPosts} from '../Reducers/AllPosts_Reucer'; 
const isProduction = process.env.NODE_ENV !== 'development'; 
const isClient = typeof document !== 'undefined'; 
const initialState = { 
    allPosts 
}; 

const middlewares = [thunk, client.middleware()]; 
const enhancers = []; 

if (!isProduction && isClient) { 
    const loggerMiddleware = createLogger(); 
    middlewares.push(loggerMiddleware); 

    if (typeof devToolsExtension === 'function') { 
     const devToolsExtension = window.devToolsExtension; 
     enhancers.push(devToolsExtension()); 
    } 
} 



const composedEnhancers = compose(
    applyMiddleware(...middlewares), 
    ...enhancers 
); 
const store = createStore(
    rootReducer, 
    initialState, 

    composedEnhancers, 
); 

export default store; 

樣品組分

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

import gql from 'graphql-tag'; 

import * as postActions from '../../Redux/Actions/postActions'; 


class Home extends Component{ 
    componentWillMount(){ 
     // console.log('From Will Mount',this.props.posts) 
    } 
    renderAllPost(){ 
     const {loading,posts} = this.props; 

     if(!loading){ 
      return posts.map(data => { 
       return <li key={data.id}>{data.title}</li> 
      }) 
     }else{ 
      return <div>loading</div> 
     } 
    } 
    render(){ 
    console.log(this.props); 
     return(
      <div> 

       {this.renderAllPost()} 

      </div> 
     ) 
    } 
} 


//start from here 
const GetallPosts = gql` 
query getAllPosts{ 
    posts{ 
    id 
    title 
    body 
    } 
} 
`; 

// const mapStateToPros = (state) => ({ 
//  allPosts:state.allPosts 
// }); 

const mapDispatchToProps = (dispatch) => ({ 
    actions:bindActionCreators(
     postActions, 
     dispatch 
    ) 
}); 


const ContainerWithData = graphql(GetallPosts,{ 
    props:({ data:{loading,posts} }) => ({ 
     posts, 
     loading, 
    }) 
})(Home) 


export default connect(
    // mapStateToPros, 
    // mapDispatchToProps 
)(ContainerWithData) 
+1

我想看看這個PR https://開頭github.com/apollographql/apollo-client/pull/1487這增加了調用resetStore的選項,而不必重新查看已查看的查詢 – Alastair

回答

1

您可以

getStoredState({ storage: localforage }, (err, rehydratedState) => { ... } 

我也希望能有一個不同的方式直接注入了Redux-持續狀態爲阿波羅的客戶端,檢查Delay Render Until Rehydration Complete