1

in our project we have around 10 animations that are using react-lottie library and are loaded with loadable-component library. Some of these animations are crashing on Gatsby development environment. I have managed to narrow down which ones are failing on my end and there were 2.

The component is built like this:

@LottieComponent.tsx
import React, { CSSProperties } from 'react';
import Lottie from 'lottie-react';
import json from './lottieAnimation.json';

interface Props {
  styles?: CSSProperties;
}

export default ({ styles }: Props) => (
  <Lottie style={styles} animationData={json} />
);

Then we use code splitting:

@index.tsx

import loadable from '@loadable/component';

const ExchangeInfographic = loadable(
  () => import('./animationComponents/ExchangeGraphic')
);

export {
  ExchangeInfographic
};

Then we import the component into the module like this:

import { ExchangeInfographic } from '../../components/Infographic';

const ExampleComponent = () => {
  const [animationWasRendered, setAnimationWasRendered] = useState(false);
  return (
    <ReactVisibilitySensor
      onChange={(isVisible) => {
        isVisible && setAnimationWasRendered(true);
      }}
      partialVisibility
    >
      <SectionCustomComponent>
        <Container>
            <Col>
              {animationWasRendered ? <ExchangeInfographic /> : <></>}
            </Col>
          </Row>
        </Container>
      </Section>
    </ReactVisibilitySensor>
  );
};
export default ExampleComponent;

The error that I get in the console is:

react-dom.development.js:23966 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `InnerLoadable`.

I have check the possible reasons for this error message and found this thread: https://github.com/facebook/react/issues/13445 and Code splitting/react-loadable issue

but it doesn't look as if the dynamic import would fail. The confusing part is that, why would it only crash on some animations and the other work fine every time. O.o

Would you have an idea what am I missing?

Thanks for any suggestions!

Digital Dom
  • 412
  • 5
  • 12

2 Answers2

0

I'm not sure if it will fix the issue because I don't know all the specs nor your use-case, but this export seems odd to me:

@index.tsx

import loadable from '@loadable/component';

const ExchangeInfographic = loadable(
  () => import('./animationComponents/ExchangeGraphic')
);

export {
  ExchangeInfographic
};

Have you tried something like:

@index.tsx

import loadable from '@loadable/component';

const ExchangeInfographic = loadable(
  () => import('./animationComponents/ExchangeGraphic')
);

export ExchangeInfographic
Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • 1
    Thanks for having a look Ferran. :) so in the index.ts we are exporting 10 components like so: export { ExchangeInfographic, AnotherInfographic, AndAnotherInfographic } I tried exporting just the faulty one and it still crashes. Thank you for your interest :) I remember you from other gatsby stackoverflow. :) – Digital Dom Feb 02 '21 at 17:49
  • It doesn't work either without code-splitting. O.o So that would rule out loadable, right? I was even checking maybe these json files are somehow corrupt. It just astounds me why these 2. I checked the files against json formatter and it shows that file is fine. – Digital Dom Feb 03 '21 at 09:06
  • Yes the frontmatter could be fetched properly but it may be wrongly interpreted by Lottie. Anyway, the idea is to try it with loadable and then apply the code-splitting – Ferran Buireu Feb 03 '21 at 09:15
0

So after few months I decided to give it another try at this weird bug.

Explanation of the issue:

ExchangeInfographic react component had a file name like this ExchangeInfographic.tsx

The json file containing json for the lottie animation had a file name like this exchangeInfographic.json

For some reason when the name of the json file and react component file was the same (except for capital letter for react component) after importing the component like this

import {ExchangeInfographic} from 'path to the file;'

It would return an object instead of function.

To fix it, I just changed the name of the file where json was to for example exchange.json

It's a kind of magic. It's a kind of maaagiiic...

Digital Dom
  • 412
  • 5
  • 12