Spinner isn't not Spinning in Nextjs 14 (Server Side)
mahsanr44 opened this issue · 9 comments
I'm adding react-spinners
in my Next.JS app but isn't spinning.
Here's my code:
import { ClimbingBoxLoader} from "react-spinners";
export default function Home() {
return (
<div>
<ClimbingBoxLoader
color="#36d7b7"
loading
speedMultiplier={2}
/>
<MyComponent />
</div>
);
}
I have tested by using use client
and it's working fine on the Client Side but I want it to be useful on the Server Side too.
i'll need to spent some time looking into how to handle the new server component paradigm. I think it's probably not working because the animation are created outside of the component
https://github.com/davidhu2000/react-spinners/blob/main/src/ClimbingBoxLoader.tsx#L7-L21
so maybe that code isn't executed after the code is sent to the client
Yeah, you're right, this could be the one of reasons.
Take your time and fix it.
Thanks
client-side animation stuff cannot be rendered on the server. They need to be marked as client component to work. Its not something that's fixable imo.
For now I just force all my loaders to be client components with a fallback for server side :
"use client"
import React, { useEffect, useState } from "react"
import { ClipLoader } from "react-spinners"
export const Loader = ({ size }: { size: number }) => {
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
return (
<React.Fragment>
{isClient ? (
<ClipLoader ... />
) : (
<ServerSideSpinner ... />
)}
</React.Fragment>
)
}
ServerSideSpinner is a regular spinner animated with tailwind.
Not sure this is a good approach, but it might help someone.
Don't do this, make a separate file, add "use client" tag on top, import the spinner and immediately export it as const or default (,ur choice) and import this spinner in your pages.
i haven't had time to work on this recently, but one potential approach would be add use client
on top of each loader, and add a setState call for each animation. This ensures it will run on the client.
const [animation] = useState(createAnimation(...))
a quick test locally does seem to work, just need to update it all. Maybe hack on it in a coming weekend.
i thought maybe using next dynamic could do it, but the create Aniamtion still doesn't run on the client
const Loader = dynamic(() => import("react-spinners/ClimbingBoxLoader"), { ssr: false });
const [animation] = useState(createAnimation(...))
This will execute createAnimation
on every render uselessly, I would advise using a callback
const [animation] = useState(() => createAnimation(...))