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

Error when working with snapshots #25

Closed
rakeshpai opened this issue Dec 21, 2017 · 4 comments
Closed

Error when working with snapshots #25

rakeshpai opened this issue Dec 21, 2017 · 4 comments

Comments

@rakeshpai
Copy link

rakeshpai commented Dec 21, 2017

I'm using a tool similar to react-snap, and can verify that I'm setting window.__LOADABLE_COMPONENT_IDS__ = [2].

Then, as specified in the react-snap docs, I'm doing the following:

loadComponents().then(() => hydrate(...))

However, loadComponent throws the following error:

Uncaught TypeError: Cannot read property 'Symbol(loadable)' of undefined
    at loadComponents.js:21
    at Array.map (<anonymous>)
    at r (loadComponents.js:20)
    at Object.<anonymous> (index.js:27)
    at t (bootstrap 056c276262f9a7299fc4:49)
    at Object.<anonymous> (main.661463cf.js:3846)
    at t (bootstrap 056c276262f9a7299fc4:49)
    at bootstrap 056c276262f9a7299fc4:144
    at bootstrap 056c276262f9a7299fc4:144

The problem is here, since componentTracker.get(id) is undefined.

I set breakpoints in componentTracker, and found that the components object in componentTracker.js is just an empty object. This is expected - loadComponent is the first thing to get called.

This is what my index.js looks like:

import React from 'react';
import { hydrate, render } from 'react-dom';
import App from './App';

import { loadComponents } from 'loadable-components';
import { getState } from 'loadable-components/snap';

const snapSaveState = () => {
  document.querySelector('html').setAttribute(
    'data-snap-state',
    JSON.stringify(getState())
  );
};

const rootElement = document.getElementById('root');
if (rootElement.hasChildNodes()) {
  const snapState = document.querySelector('html').getAttribute('data-snap-state');

  if(snapState) {
    console.log(JSON.parse(snapState));  // This shows the expected value
    Object.entries(JSON.parse(snapState)).forEach(([key, value]) => window[key] = value);
  }

  loadComponents().then(() => {
    console.log('hydrating'); // This is never called
    hydrate(<App />, rootElement);
  });
} else {
  render(<App />, rootElement, snapSaveState);
}

I'm using a data-attribute on the HTML tag instead of setting an inline script tag because of CSP limitations. However, in essence, this shouldn't change anything, since I've made the correct global available before calling loadComponents.

Am I doing something wrong?

@rakeshpai
Copy link
Author

I'm a little perplexed, since I can't understand how the components object in componentTracker.js could ever be populated when loadComponents is called. The hydration of the app itself comes after loadComponents is complete, so the app can't have populated the component cache yet. So, when calling loadComponents, the components object will always be empty.

I'm pretty sure I'm doing something wrong. :)

@stereobooster
Copy link

stereobooster commented Dec 27, 2017

const snapSaveState = () => {
  document.querySelector('html').setAttribute(
    'data-snap-state',
    JSON.stringify(getState())
  );
};

not sure where you got this snippet from. Use exact code from readme:

window.snapSaveState = () => getState();

UPD:

I'm using a tool similar to react-snap, and can verify that I'm setting

I missed that part

@gregberge
Copy link
Owner

The current version of loadable-components has some issues with registering. I have to rewrite that part to handle all cases.

@gregberge
Copy link
Owner

This issue should be solved in v1. You should give a try, feel free to open a new issue if you experienced any problem.

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

3 participants