question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

After server render the page, use initial state on client side, actions of further query does not change state

See original GitHub issue

This is a SSR setup, all the html string and store state has been retrieved and sent to browser client, and redux store is initialized correctly. But the query generated by operation in browser does not change the store state at all, although the query is sent to server and get response, even the APPLLO_QUERY_INIT and APOLLO_QUERY_RESULT action is logged by redex dev tool. And no error produced.

The same code runs through non-SSR can work correctly.

It seems that apollo reducer does not handle the actions or failed to process the action but return previous state, so state is not changed.

There is one finding I am not sure whether it is the cause : In the store state received from server in SSR mode, the apollo.queries object has one query which id is 2, but if run through local, the id is 1. After server rendering, the first action in browser is ‘@@INIT’, and second APOLLO_QUERY_INIT and third APOLLO_QUERY_RESULT_CLIENT and the queryId in second and third action is 1

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
shendepucommented, Jan 17, 2017

It is simple pagination query. server return first page of data, and in browser, go to next page. It runs completely fine if app is run locally.

Here is some redux dev tool action and state snapshots:

This should be generated by component loaded in browser from initial state by apollo-client

image

And it is strange to me that apollo.queries has the query which id is 2. but it is 1 if run from local.

image

Below is generated by go to next page on browser

We can see the action actually has data image

but the state does not change at all.

image

The component setup is

const PositionsIndexContainerWithData = graphql(POSITION_LIST_QUERY, {
  options (props) {
    return {
      variables: {
        pageIndex: 0
      }
    }
  },
  props: ({ ownProps, data }) => {
    const { loading, mantle, fetchMore } = data
    console.log('PositionsIndexContainerWithData -- props: ')
    console.log(mantle)
    return {
      ...ownProps,
      loading,
      data,
      emplPositions: mantle && mantle.emplPositions && mantle.emplPositions.edges,
      pageInfo: mantle && mantle.emplPositions && mantle.emplPositions.pageInfo,

      loadMoreEntries (pageIndex) {
        return fetchMore({
          variables: { pageIndex },
          updateQuery: (previousResult, { fetchMoreResult }) => {
            return Object.assign({}, previousResult, {
              mantle: fetchMoreResult.data && fetchMoreResult.data.mantle
            })
          }
        })
      }
    }
  }
})(PositionsIndexContainer)
0reactions
shendepucommented, Jan 17, 2017

I hunt it down the problem. It is my issue.

I have below code to makeRootReducer, the missingReducers part is to avoid redux complain if initial state has keys that combineReducers do not have.

export const makeRootReducer = (apolloClient, asyncReducers, initialState) => {
  let missingReducers = { }
  if (initialState !== undefined && typeof initialState === 'object') {
    for (let key in initialState) {
      if (!asyncReducers.hasOwnProperty(key)) {
        missingReducers[key] = () => initialState[key]
      }
    }
  }
  return combineReducers({
    location: locationReducer,
    form: formReducer,
    apollo: apolloClient.reducer(),
    auth: authReducer,
    ...asyncReducers,
    ...missingReducers
  })
}

It works fine when running locally because there is no initial state at all, so missingReducers calculation is simply ignored.

The fix is simple that just move ...missingReducers to the top, otherwise, the apollo reducer is override incorrectly.

return combineReducers({
    ...missingReducers, // important to be first!!! If initial state has key of sync reducer,
                        // it will be in missingReducers, put it at first order, so they will
                        // be override by below
    location: locationReducer,
    form: formReducer,
    apollo: apolloClient.reducer(),
    auth: authReducer,
    ...asyncReducers
  })

This can be closed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Managing local state | Full-Stack Quickstart - Apollo GraphQL
Now, whenever we query one of our client-side schema fields, the value of our corresponding reactive variable is returned. Let's write a query...
Read more >
Server Rendering - Redux - JS.ORG
Because the client side executes ongoing code, it can start with an empty initial state and obtain any necessary state on demand and...
Read more >
Refreshing Server-Side Props - Next.js - Josh W Comeau
This is because the page doesn't know that the underlying data has changed. After the page is server-rendered, those props are immutable.
Read more >
How to implement server-side rendering in your React app in ...
We will use the state passed in the response for creating the initial state on client-side. Before you get started, clone/download the complete ......
Read more >
getInitialProps - Data Fetching - Next.js
Note that irrespective of rendering type, any props will be passed to the page component and can be viewed on the client-side in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found