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

Not working with react-redux-firebase "TypeError: Converting circular structure to JSON" #91

Closed
tky5622 opened this issue May 13, 2018 · 7 comments

Comments

@tky5622
Copy link

tky5622 commented May 13, 2018

I tryed to use react-redux-firebase with next-redux-wraper and I ran into "TypeError: Converting circular structure to JSON" error.

This is also reported in react-redux-firebase repo and someone said the issue seems to be solved by creating withRedux HOC but there is no clear answer about the cause of issue and solution.

So, I was wodering if you can deal with this probrem.

bug(firebase): firebase error "TypeError: Converting circular structure to JSON"
prescottprue/react-redux-firebase#230

example of redux-wrapper HOC.
https://gist.github.com/artisin/d56750d955ff4a60ed11e6a714cbd1bd

`TypeError: Converting circular structure to JSON
at JSON.stringify ()
at module.exports (/Users/takuya/program/gaudiy-react-next/node_modules/htmlescape/htmlescape.js:24:15)
at NextScript.render (/Users/takuya/program/gaudiy-react-next/node_modules/next/dist/server/document.js:313:81)
at processChild (/Users/takuya/program/gaudiy-react-next/node_modules/react-dom/cjs/react-dom-server.node.development.js:2191:18)
at resolve (/Users/takuya/program/gaudiy-react-next/node_modules/react-dom/cjs/react-dom-server.node.development.js:2048:5)
at ReactDOMServerRenderer.render (/Users/takuya/program/gaudiy-react-next/node_modules/react-dom/cjs/react-dom-server.node.development.js:2333:22)
at ReactDOMServerRenderer.read (/Users/takuya/program/gaudiy-react-next/node_modules/react-dom/cjs/react-dom-server.node.development.js:2307:19)
at renderToStaticMarkup (/Users/takuya/program/gaudiy-react-next/node_modules/react-dom/cjs/react-dom-server.node.development.js:2690:25)
at _callee3$ (/Users/takuya/program/gaudiy-react-next/node_modules/next/dist/server/render.js:341:100)
at tryCatch (/Users/takuya/program/gaudiy-react-next/node_modules/regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (/Users/takuya/program/gaudiy-react-next/node_modules/regenerator-runtime/runtime.js:296:22)
at Generator.prototype.(anonymous function) [as next] (/Users/takuya/program/gaudiy-react-next/node_modules/regenerator-runtime/runtime.js:114:21)
at step (/Users/takuya/program/gaudiy-react-next/node_modules/@babel/runtime/helpers/asyncToGenerator.js:12:30)
at _next (/Users/takuya/program/gaudiy-react-next/node_modules/@babel/runtime/helpers/asyncToGenerator.js:27:9)
at

Disposing inactive page(s): /
`

@kirill-konshin
Copy link
Owner

This library does not do anything specific with Firebase or serialization/deserialization of state. You can use custom serializer if needed: https:/kirill-konshin/next-redux-wrapper#custom-serialization-and-deserialization

@optimistiks
Copy link

I'm experiencing this issue, with NextJS + next-redux-wrapper + react-redux-firebase. Several things involved here:

  1. react-redux-firebase adds firebase object to the store, that makes it impossible to serialize the store.
    https:/prescottprue/react-redux-firebase/blob/master/src/enhancer.js#L127
  2. next-redux-wrapper passes the store instance as part of initial props, together with initialState and the rest of the stuff.
    https:/kirill-konshin/next-redux-wrapper/blob/master/src/index.js#L85
  3. By design, NextJS serializes initial props when rendered on server.(https:/zeit/next.js#fetching-data-and-component-lifecycle)

So what happens is NextJS tries to serialize the store object, as part of the initial props, and fails.

In that example - https:/zeit/next.js/tree/master/examples/with-redux - store is not passed to initial props, so I'm thinking that it probably shouldn't be done in the next-redux-wrapper either.

Considering that Redux does not put any constraints on what you can put into the store, and NextJS clearly says that Make sure the returned object from getInitialProps is a plain Object and not using Date, Map or Set., it seems like the fix should be implemented on next-redux-wrapper side, because store is not guaranteed to be a plain Object.

prescottprue/react-redux-firebase#230

@kirill-konshin
Copy link
Owner

Nice explanation! Like I said before, you may add custom serializer/deserializer https:/kirill-konshin/next-redux-wrapper#custom-serialization-and-deserialization there you can do whatever you want with the store's state.

@optimistiks
Copy link

optimistiks commented Dec 5, 2018

It's not about serializing the state. State serializes just fine. It's about serializing store instance, that is being returned from getInitialProps right there https:/kirill-konshin/next-redux-wrapper/blob/master/src/index.js#L85.

Quote from NextJS: Data returned from getInitialProps is serialized when server rendering, similar to a JSON.stringify. Make sure the returned object from getInitialProps is a plain Object and not using Date, Map or Set.. NextJS tries to serialize store instance, and fails.

In this example https:/zeit/next.js/tree/master/examples/with-redux, store instance is not part of initial props, and it works fine.

@kirill-konshin
Copy link
Owner

kirill-konshin commented Dec 5, 2018

Got it.

The difference is that store in the example is created twice in server mode, first time in getInitialProps and then using serialized state in constructor, the instance created in getInitialProps is temporary. This lib works a bit differently, it tries to reuse same instance if possible even in server mode.

Technically, we can get rid of this behavior. I need to do some research :)

This is the discussion vercel/next.js#4295 (review)

kirill-konshin added a commit that referenced this issue Dec 5, 2018
Fix #91 Not working with react-redux-firebase "TypeError: Converting circular structure to JSON"
Updated dependencies
@kirill-konshin
Copy link
Owner

Published 2.1.0. Thanks @optimistiks.

@dorian-marchal
Copy link

dorian-marchal commented Feb 27, 2019

@kirill-konshin An other way to deal with this issue would be to make the store instance unserializable:

store.toJSON = () => undefined;

This is probably a bad idea (maybe someone would really want to serialize it?) but it can be used to keep the same store instance between getInitialProps and render on server side.

EDIT: Or maybe you can wrap it in an unserializable object:

const unserializableProps = { store };
unserializableProps.toJSON = () => undefined;

return {
    unserializableProps,
    isServer,
    initialState: config.serializeState(store.getState()),
    initialProps,
};

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

No branches or pull requests

4 participants