New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Home fetch run twice #983

Closed
IDrinkMoreWater opened this Issue Nov 20, 2016 · 8 comments

Comments

Projects
None yet
9 participants
@IDrinkMoreWater
Copy link

IDrinkMoreWater commented Nov 20, 2016

/src/routes/home index.js: fetch

import React from 'react';
import Home from './Home';
import fetch from '../../core/fetch';
import Layout from '../../components/Layout';

export default {

  path: '/',

  async action() {
    const resp = await fetch('/graphql', {
      method: 'post',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        query: '{news{title,link,contentSnippet}}',
      }),
      credentials: 'include',
    });
    const { data } = await resp.json();
    if (!data || !data.news) throw new Error('Failed to load the news feed.');
    return {
      title: 'React Starter Kit',
      component: <Layout><Home news={data.news} /></Layout>,
    };
  },

};

**server.js **

app.use('/graphql', expressGraphQL(req => ({
  schema,
  graphiql: process.env.NODE_ENV !== 'production',
  rootValue: { request: req },
  pretty: process.env.NODE_ENV !== 'production',
})));

debug log,expressGraphQL will run twice

@IDrinkMoreWater IDrinkMoreWater changed the title Home Home fetch twice Nov 20, 2016

@IDrinkMoreWater IDrinkMoreWater changed the title Home fetch twice bug: Home fetch run twice Nov 20, 2016

@xaclincoln

This comment has been minimized.

Copy link

xaclincoln commented Dec 30, 2016

add console.log('fetch finished') after await fetch('/graphql'.....) in /src/routes/home index.js file, then refresh the browser, the console in browser and the console of my laptop both printed fetch finished. Is this expected? I have thought api requests only happened on the server.

@jorrit

This comment has been minimized.

Copy link
Contributor

jorrit commented Jan 8, 2017

Same here, all fetches are ran twice. It seems there is no way in which the state is saved in the HTML so it doesn't need to be refetched on the client.

I am now passing the data found server-side in action() to the html and feeding it in client.js to the action() clientside.

@buildbreakdo

This comment has been minimized.

Copy link
Contributor

buildbreakdo commented Jan 17, 2017

@jorrit Passing data down inside an element and picking it up client side when the rerender check happens is the correct thing to do. Example in this project is incomplete.

@DylanYasen

This comment has been minimized.

Copy link

DylanYasen commented Jan 22, 2017

This is not a bug my friend.

since the routes are universal, it will first run on the server and then run again on the client.

This is basically one of the major point of using isomorphic architecture: to prefetch the data on the server.

I personally use redux for data handling. So basically when request comes in, on server side I would fetch the data, put the data in redux store, render the route, and at last, pass down the rendered page with the redux state to the client.

Then on the client side, I would check if the data is already in the redux store. if it is, then there is no need to fetch the data again.

export default {

  path: '/data',

  async action({ store }) {
    const data = store.getState().data;
    if (!data) {
      console.log('no data. fetch now');
      await store.dispatch(fetchData());
    }else{
      console.log('already got the data. don\'t fetch');
    }
    
    return {
      component: <Layout><DataView data={data}/></Layout>,  
      // I'm passing the data to the component just for demonstration purposes 
      // would normally use higher order component to decorate the <DataView> with the data when using redux
    };
  },

};
@jorrit

This comment has been minimized.

Copy link
Contributor

jorrit commented Jan 23, 2017

You're right, it is not a bug. It is a consequence of the fact that the default react-starter-kit branch does not contain a store and doesn't serialize the data in HTML. As such, the server side prefetching does not prevent client-side fetching. Maybe something simple can be added without pulling in redux.

@iDVB

This comment has been minimized.

Copy link

iDVB commented May 4, 2017

@DylanYasen, two questions....

  1. is your code sample pseudo code, in that would that if (!data) check more then just existence, or would it be diving into the type of data to validate its contents?

  2. What about in the case of a dynamic route. Say a VideoDetails page where the url is of type domain.com/video/24234 if all we do is check for existence... as you browse from videodetails page for video1 to videodetails page for video2 the content would never change since that check if (!data) will always be true.

@Shadowman4205

This comment has been minimized.

Copy link

Shadowman4205 commented Jul 12, 2017

Did you find any recommended solution for this?

@shishirarora3

This comment has been minimized.

Copy link

shishirarora3 commented Jul 12, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment