preact: Lazy loading styled-components component triggers warning message incorrectly
Reproduction
https://github.com/TLadd/preact-styled-components-lazy-load-warning. The relevant files are
- https://github.com/TLadd/preact-styled-components-lazy-load-warning/blob/master/src/index.js
- https://github.com/TLadd/preact-styled-components-lazy-load-warning/blob/master/src/StyledDiv.js
preact@10.4.4
Steps to reproduce
Load the app and observe the following warning message is printed:
The component styled.div with the id of “sc-AxjAm” has been created dynamically. You may see this warning because you’ve called styled inside another component. To resolve this only create new StyledComponents outside of any render method and function component.
This warning occurs only when lazy loading a styled component or lazy loading something that renders a styled component with preact. The warning message is not printed if a dynamic import is not used or if using React instead of preact.
Looking at styled-components, it’s triggering this warning message if calling useRef
doesn’t throw when declaring the component.
Expected Behavior
The warning message should not be printed.
Actual Behavior
The warning message is printed.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 27 (13 by maintainers)
Hiya 👋
I’ve put in the warning and it triggers when we a hook doesn’t throw during StyledComponent creation. I’m not sure what context this permissiv behaviour happens in, but it does seem like a tiny issue in
preact/compat
to me as during the time of import we shouldn’t be inside any component context; that being said it’s safe to ignore.The reason why I’ve proposed the change and we’ve added it is that this is still a common mistake when styled-components are used. We get a lot of issues that relate to dynamically created components: unexpected edge cases that are usually impossible, memory leaks on the client-side and in SSR, out of memory errors, rerender bugs triggered by this, etc.
After having seen probably hundreds of these issues and comments, it’s clear that once people create more than a thousand components, telling them to track down the few cases where they’re dynamically created (and explaining this to beginners) is a daunting ask.
Hence this warning was introduced to rule this mistake out entirely, which has mostly eliminated this category of issues entirely 😅
@heymartinadams that “total hack” how you call it seems a bit off to me. Adding the react-refresh runtime manually doesn’t feel right. @JoviDeCroock spent quite some time to create prefresh - the react-refresh alternative for preact. It even features a next.js plugin (https://github.com/JoviDeCroock/prefresh/tree/main/packages/next).
As @developit mentioned I maintain a next.js plugin that will take care of the aliasing of react to preact and also includes prefresh: https://github.com/sventschui/next-plugin-preact . I guess this plugin would be your best bet for a stable setup. If you experience any issues with that and styled-components it would be helpful if you could share a small reproduction project where we could take a closer look.
@marvinhagemeister After having installed the last version of
preact-render-to-string
with your fix, the errors have disappeared for both my small reproduction example and our larger codebase where we use preact with next in the real world. 🎉 🎉 🎉Thanks again for looking into this.
@heymartinadams ~that seems like a React error, not a Preact error.~ You’re likely missing
preact/debug
. Here’s how to enable it in Next.js: https://github.com/developit/nextjs-preact-demo/blob/77f928b754910f8d44687a3a6eb38c3e08f646c3/next.config.js#L33-L40There’s also a plugin that does all this automatically, which we’re likely going to be marking as an official Preact project: https://github.com/sventschui/next-plugin-preact
@marvinhagemeister okay that’s very interesting. I just tried also to completely delete the node_modules folder, reinstall with both npm and yarn, but i keep getting the error, especially when navigating between the /about route and the home route. This never happens the first time a page is loaded, but usually the second time,after i refresh the page. I’ve also completely cleared the local
.next
folder to ensure that this isn’t some cache related issue as well…I’ll try to investigate some more and ask some of my colleagues next week to try this out on their machines as well, to rule out that there is something fishy going on with my system.
EDIT: Also to clarify those errors are occurring during SSR on the server, so look out for them in the terminal that’s running the dev server, not on the client. (see below)
@tbgse did the following:
next.config.js
package.json
@heymartinadams the
next-plugin-preact
already includesprefresh/next
and thus you do not have to add it manually.Ok, I think I got to the bottom of this. We correctly throw an error when
preact/debug
is present. Without anypreact/debug
imports we won’t display any messages or errors only intended for debugging purposes.This issue can be resolved by adding
import "preact/debug"
at the top of the main entry file.