remix-run / remix

Build Better Websites. Create modern, resilient user experiences with web fundamentals.
https://remix.run
MIT License
30.15k stars 2.55k forks source link

Simple app made via Remix QuickStart can error out on some imported external components during SSR #10277

Closed Writ3r closed 2 days ago

Writ3r commented 4 days ago

Reproduction

  1. Runnpx create-remix@latest
  2. From the folder you just made via quickstart, run npm i react-countup
  3. Inside app/routes/_index.tsx add CountUp import: import CountUp from 'react-countup';
  4. Somewhere in the Index return in _index.tsx, render the component <CountUp duration={1} end={1} decimals={0}></CountUp>
  5. Run npm run dev and notice the page errors out on the SSR. If you force the component to render client-side only it works fine.

Note - this also happens for react-bootstrap with the 'Col' component as well, which interestingly enough a hacky workaround is to just copy the Col component code out of the react-bootstrap repository and paste it into a local file called 'Col' and it works fine if you import it from that local file.

If I'm doing something wrong here let me know and close out this issue, I'm new to using Remix but I can't find definitive info on why these fairly well-used components would fail to render like this.

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700K
    Memory: 7.92 GB / 31.80 GB
  Binaries:
    Node: 20.18.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.22621.3527

Used Package Manager

npm

Expected Behavior

The component renders correctly or at least doesn't error out during the server-side render

Actual Behavior

The run dev output shows this error:

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check your code at _index.tsx:37.
    at Index
    at RenderedRoute (C:\Users\lucas\Downloads\testt\node_modules\react-router\dist\umd\react-router.development.js:539:7)
    at Outlet (C:\Users\lucas\Downloads\testt\node_modules\react-router\dist\umd\react-router.development.js:1186:28)
    at App
    at body
    at html
    at Layout (C:/Users/lucas/Downloads/testt/app/root.tsx:22:19)
    at RenderedRoute (C:\Users\lucas\Downloads\testt\node_modules\react-router\dist\umd\react-router.development.js:539:7)
    at RenderErrorBoundary (C:\Users\lucas\Downloads\testt\node_modules\react-router\dist\umd\react-router.development.js:486:7)
    at DataRoutes (C:\Users\lucas\Downloads\testt\node_modules\react-router-dom\server.js:130:3)
    at Router (C:\Users\lucas\Downloads\testt\node_modules\react-router\dist\umd\react-router.development.js:1207:17)
    at StaticRouterProvider (C:\Users\lucas\Downloads\testt\node_modules\react-router-dom\server.js:67:3)
    at RemixErrorBoundary (C:\Users\lucas\Downloads\testt\node_modules\@remix-run\react\dist\errorBoundaries.js:41:5)
    at RemixServer (C:\Users\lucas\Downloads\testt\node_modules\@remix-run\react\dist\server.js:48:3)
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
    at renderElement (C:\Users\lucas\Downloads\testt\node_modules\react-dom\cjs\react-dom-server.node.development.js:6120:9)
    at renderNodeDestructiveImpl (C:\Users\lucas\Downloads\testt\node_modules\react-dom\cjs\react-dom-server.node.development.js:6181:11)
    at renderNodeDestructive (C:\Users\lucas\Downloads\testt\node_modules\react-dom\cjs\react-dom-server.node.development.js:6153:14)
    at renderNode (C:\Users\lucas\Downloads\testt\node_modules\react-dom\cjs\react-dom-server.node.development.js:6336:12)
    at renderChildrenArray (C:\Users\lucas\Downloads\testt\node_modules\react-dom\cjs\react-dom-
Writ3r commented 4 days ago

A bit more info - I gave nextjs a shot to see if it'd render these correctly or not (for more datapoints on if these components work with SSR in general), and it did tell me the CountUp component should be only client rendered because it uses a useRef, however the react-bootstrap Col had no problems with SSR. So there is some sort of an issue here, just the CountUp component maybe was a worse example of this bug than the react-bootstrap Col is.

Writ3r commented 2 days ago

I got a bit deeper into the weeds of testing this on nextjs, and it did run into similar issues with other components. I am thinking at this point that possibly the recent versions of react are not playing well in conjunction with older components when SSR is used in general. So I'll close out this issue here since I'm doubting remix is the cause of this.