-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: CSS animations jump between Suspense children and fallback #23217
Comments
From what I ran, I switched out the throwPromise component with one that simply loaded a solid red div to better visualize the results. I also added I hope this helped somewhat. The result: Sandbox: Here is the React code: import { Suspense, useEffect, useState } from "react";
import "./styles.css";
function Loading() {
return <div className="loading" />;
}
const ADiv = () => <div className="cube"></div>;
export default function App() {
const [suspended, setSuspended] = useState(false);
useEffect(() => {
setTimeout(() => setSuspended((s) => (s ? s : !s)), 4000);
}, []);
return (
<Suspense fallback={<Loading />}>
{console.log(suspended)}
{suspended ? <ADiv /> : <Loading />}
</Suspense>
);
} and CSS @keyframes fade {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.loading {
width: 5em;
height: 5em;
background-color: currentColor;
animation: fade 1s forwards;
animation-iteration-count: infinite;
}
.cube {
width: 5em;
height: 5em;
background-color: red;
} |
Thank you for looking into this issue but I'm afraid your answer does not help me. I have added a bit more details to the description and another example that shows what I thought should happen. I hope that clarifies the problem a bit. |
That's not something we plan to allow. However, you're right animating from/to fallback is an important use case. I don't think we have a great solution for it today but it will be a part of a future effort to add first-class animations to React. See reactjs/rfcs#154 (comment) for thoughts on that. |
Thanks for providing the link to your comment. It was rather useful for understanding the problem. I am closing this issue because to my knowledge the reconciliation of children and fallback would have been the only solution. |
The following setup is a workaround for this issue. Wrap the relevant tree into a loading boundary component that tracks the loading state, has a context to change it and renders the loading indicator in addition to the children (which should always render to nothing when loading). Instead of using the indicator as a fallback use a toggle component that changes the state fo the context when entering or leaving using a layout effect but renders nothing. |
React version: 17.0.2, 18.0.0-rc0
Steps To Reproduce
div.fade
that has has an animation duration of 5s.Link to code example: https://codesandbox.io/s/rough-water-zxc2m
The current behavior
The CSS animation resets probably because the DOM element is replaced. Every 2s the animation starts from the beginning.
The expected behavior
The Suspense's children and fallback are reconciled and the DOM remains unmodified so that the animation can complete. In other words, I think it should work like this example: https://codesandbox.io/s/eager-river-ww04i. This would make it much easier to build smooth loading indicators using a mix of Suspense and conditional rendering.
The text was updated successfully, but these errors were encountered: