'How to import Lottie component?
Remix is prone to the following error when using import on top-level components TypeError: Cannot read properties of undefined (reading 'root')
.
So I've done as they recommend and have the following imports.server.tsx
file.
export * from "lottie-react";
Then my component app.tsx
looks exactly like this lottie example.
import React from "react";
import * as Lottie from "../imports.server";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";
export default function App() {
return (
<>
<h1>lottie-react - Component</h1>
<Lottie animationData={groovyWalkAnimation} />;
</>
);
}
but I get the following error
JSX element type 'Lottie' does not have any construct or call signatures.ts(2604)
Edit 1:
The following seems to have worked for imports:
imports.server.tsx
import Lottie from "lottie-react";
export default Lottie;
AppTry.tsx
import React from "react";
import Lottie from "../imports.server";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";
export default function AppTry() {
// console.log(LottieModule);
return (
<>
<h1>lottie-react - Component</h1>
<Lottie animationData={groovyWalkAnimation}></Lottie>
</>
);
}
Now the various paramaters like "animationData" and "autoPlay" pop up on the Lottie component which I assume means the import is working? However I am now getting this error when rendering AppTry.tsx
?
react.development.js:220 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of
AppTry
.
Edit 2:
import { useLottie } from "lottie-react";
import Lottie from "lottie-react";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";
const Example = () => {
const options = {
animationData: groovyWalkAnimation,
loop: true,
autoplay: true,
};
const { View } = useLottie(options);
return View;
};
const Example1 = () => {
return <Lottie animationData={groovyWalkAnimation} />;
};
export const TopicOverview = () => {
return (
<div className="space-y-20">
<Example1></Example1>
<Example></Example>
</div>
);
};
Solution 1:[1]
Looks like it has to do with your way of importing Lottie.
Shouldn't you import Lottie like this?:
import Lottie from "lottie-react";
Solution 2:[2]
I also struggled to get this working in Remix. You can do the lazy load import somewhere higher up in the tree too.
import type { LottiePlayer } from "@lottiefiles/lottie-player";
import { useEffect } from "react";
interface LottieCompProps {
src: LottiePlayer["src"];
style?: Partial<LottiePlayer["style"]>;
}
function LottieComp({ src, style = {} }: LottieCompProps): JSX.Element | null {
// NB: otherwise, will cause app to crash. see https://remix.run/docs/en/v1/guides/constraints#third-party-module-side-effects
useEffect(() => {
import("@lottiefiles/lottie-player");
},[]);
if (typeof document === "undefined") return null;
return (
//@ts-expect-error dynamic import
<lottie-player
autoplay
loop
mode="normal"
src={typeof src === "string" ? src : JSON.stringify(src)}
style={{
...{
width: "100%",
backgroundColor: "transparent",
},
...style,
}}
/>
);
}
export default LottieComp;
Solution 3:[3]
The issue was in my root.tsx
, an ErrorBoundary()
function that called an <UnexpectedErrors/>
component.
This same component was being called in various slug.tsx
files. For some reason remix did not like this.
Having two different <UnexpectedErrors/>
and <UnexpectedErrors2/>
components - one for the slug.tsx
files and one for the index.tsx
files fixed this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Gobli |
Solution 2 | mattf96 |
Solution 3 | rowen |