I have an initial state for a component that basically doesn't render the children until after one second, which will play various CSS animations. This works fine if the page hasn't been pre-rendered.
However if the page has been pre-rendered with react-snap, then we'll actually see the component children, and then it'll disappear and play after 1 second. This is likely happening because react-snap is rendering for over 1 second, and thus the children will be rendered to the output HTML file.
I could probably store the state in Redux instead, and hard-code the visibility state in the window object. But I just wanted to check if there's some trick that I'm not aware of to get this working.
Thanks.
However if the page has been pre-rendered with react-snap, then we'll actually see the component children, and then it'll disappear and play after 1 second
This happens because you see HTML first and later React boots and re-renders everything. To prevent this you need to save state of React inside generated HTML and restore it after.
There are sections on how to do it with async components and Redux.
Highly depends on what your code is doing.
In my case I have loadable component that renders the component <Hero />, and the component has the state showAnimation which is initially set to false, but is changed to true after about 500ms. When it's set to true it will render various children components that animate in to the screen.
The problem is exactly like you explained. When you say that I need to save the state of React, are you talking about the state of Redux and LoadableComponent? How will it actually help in my case since the children have already been rendered to the HTML?
The problem is that react-snap renders the children of the component, which shouldn't be rendered immediately, but it happens in this case likely because it takes more than 500ms to render the page. So when the page is opened, the user will see the children rendered, and when React boots up, it sets the showAnimation flag to false in the constructor, and the children will disappear, and then re-appear after 500ms.
Is there something obvious that I'm doing wrong? Thanks.
When you say that I need to save the state of React, are you talking about the state of Redux and LoadableComponent?
All of them. What happens is
(almost rendered) -> (empty screen) -> (rendered)
Gotcha, but it will always erase the children and re-render them because they have been rendered to the HTML, which is my biggest problem 馃
If you don't want to prerender some parts of your application you can implement that logic inside of the component:
const NoPrerender = ({children}) => {
return navigator.userAgent === "ReactSnap" ? null : children;
}
Also, be careful with hydrate in this scenario.
That's exactly what I needed, thanks!
I basically disabled the setTimeout that changes the state, when ReactSnap is present in the User Agent. So it shouldn't cause any issues with hydrate AFAIK, but thanks for the tip!
Issue with hydrate is that if HTML from the server differs from what React renders on the client it can get in broken state.
I guess, I answered your question. Feel free to re-open