Skip to content
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

how to avoid the dup request for ssr #813

Closed
dreambo8563 opened this issue Aug 25, 2016 · 3 comments
Closed

how to avoid the dup request for ssr #813

dreambo8563 opened this issue Aug 25, 2016 · 3 comments
Labels

Comments

@dreambo8563
Copy link

fetch data in the home async router

  • visit path /
    • check the network

what I found:

  • we already have the data in the html ( server side request)
  • after for a while, the client side request sent
export default {

  path: '/',

  async action() {
    const Home = await new Promise((resolve) => {
      require.ensure([], (require) => resolve(require('./Home').default));
    });

    const resp = await fetch('http://jsonplaceholder.typicode.com/posts',
      {
        method: 'get',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
      });
    console.log("browser", process.env.BROWSER);
    const data = await resp.json();
    userInfo.news = data;

    // console.log(JSON.stringify(userInfo.news), 'before return')
    if (!data) throw new Error('Failed to load the news feed.');


    return <Home />;
  },

};
@frenzzy
Copy link
Member

frenzzy commented Aug 25, 2016

Typically, server responses with html are cached for a longer time than api because the server-side react rendering is slow, so that the visitor sees a page instantly and when the javascript is ready the data will be actualized.

However, you can share the server data to the client to reduce network usage (it seems it is already implemented in the feature/redux branch, see Readme/Customization). But the idea is very simple, all you have to do is:

  1. Create a new store (or empty object) for every http request and serialize it before sending to client, usually inside server.js, pseudocode:

    app.get('*', async (req, res, next) => {
      // ...
      const store = createStore() // => {}
      await UniversalRouter.resolve(routes, { path: req.path, store, /*...*/})
      // ...
      html += `<script>window.INITIAL_STATE=${JSON.stringify(store)}</script>`
      // ...
    })
  2. Add a wrapper (action) for each http request which will cache the result in the store, pseudocode:

    const route = {
      path: '/',
      async action({ path, store }) {
        // ...
        if (/* if page data does not exists inside store or not actual */) {
          store.data = await fetch('api-url').then(res => res.json())
        }
        // use store.data here
        // ...
      }
    }
  3. Create a new store from the initial state on the client side, usually inside client.js, pseudocode:

    function run() {
      const store = createStore(window.INITIAL_STATE) // => { data: 'your data' }
      // ...
      await UniversalRouter.resolve(routes, { path: location.pathname, store, /*...*/})
      // ...
    }

See also: A bare minimum Redux integration

@langpavel
Copy link
Collaborator

langpavel commented Aug 25, 2016

Please use data attribute for serializing JSON into document.
Instead unsafe, HTML injection vulnerable code use (like this one in feauter/redux):

<script id="source" data-initial-state={JSON.stringify(store.getState())}></script>

@dreambo8563
Copy link
Author

@frenzzy yeah, that we have done.
@langpavel thanks, assign it on the attr is a great idea. resolve the &quot issue for json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants