-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[data grid] infinite loop occurs under certain circumstances #13230
Comments
Hey @layerok ... thanks for opening this issue. |
IIUC, to trigger this issue, there needs to be an error thrown from inside the grid rendering code, which in this case is user code, right? |
Yes, in this case the error came from user code, but that doesn't matter. The error could have come from the library code. For example, an error is thrown if any translation string is missing. |
I think the issue is the error, not the infinite loop. There shouldn't be an error thrown from the translation code, everything should be complete. I would be ok with adding an error boundary to catch the error and fail gracefully, but I don't think we should start adding code to the rest of the logic because "anything might throw". It just complicates the logic too much for what it brings. |
First of all, "everything should be complete" for me is a very optimistic assumtion in this situation. If this assumtion is not true, the user's browser will crush. I don't want that. Secondly, I don't think there is only one cause to this issue. This issue won't reproduce if one of 3 conditions is absent. I don't know for sure if this is mui or react-router bug. You said that you would be ok to wrap datagrid in an error boundary to fail gracefully. I'm not sure if this will help, react-router already wraps every route in an error boundary, but it does not help. Right now I'm trying to create a minimal reproducible example to understand what the problem is. I'm creating my custom react-router and datagrid implementations, removing everything that isn't related to the problem. |
I found one interesting detail. An error that occurs while rendering a cell does not result in the infinite loop, unlike errors within the header and header filter cells. |
ok, I figured it out, it turns out that calling the router.navigate function in useEffect schedules update in a microtask that cannot be cancelled. useEffect(() => {
router.navigate(...)
}, []); You are essentially doing this useEffect(() => {
setState({...});
// react-router resolves loaders
Promise.resolve().then(() => {
// state update in a microtask
setState({...});
})
}, []) To fix the infinite loop we need to somehow cancel this microtask. Unfortunately there is no way to cancel pending navigation in react-router. But we can workaround this problem by wrapping router.navigate call in setTimeout. This way we will be able to abort the navigation before it even starts. useEffect(() => {
let timeout = setTimeout(() => {
router.navigate(...);
})
return () => clearInterval(timeout);
}, []) It also would be nice if MUI didn't emit events inside layout or passive effect, thus this problem wouldn't exist at all. But I guess this will be massive rework of the library. |
Finally, I've created a minimally reproducible example as possible That's roughly what's going on
const HomePage = () => {
const navigate = useNavigate();
useEffect(() => {
//const timeout = setTimeout(() => {
navigate({
search: "?page=2"
})
//})
return () => {
//clearTimeout(timeout)
}
}, [navigate]);
return (
<NoSsr>
<RenderSomethingThatThrows/>
</NoSsr>
);
}
const router = createBrowserRouter([
{
path: "/",
element: <HomePage />,
loader: async () => {
// remove this loader to prevent the infinite loop
return null;
},
},
]);
function App() {
return <RouterProvider router={router} />;
} |
this is not a MUI issue |
@layerok: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey. |
Steps to reproduce
Link to live example: https://codesandbox.io/p/devbox/frosty-faraday-lt52lc?file=%2Fsrc%2FApp.tsx%3A135%2C24
Steps:
Current behavior
Infinite loop
Expected behavior
No infinite loop
Context
I want to...
I have successfully completed everything listed above.
But there is one problem that occurs under certain circumstances. Infinite loop.
The circumstances are as follows.
viewportInnerSizeChange
event listenerIf all of the circumstances are true, the infinite loop is guaranteed.
If one of the circumstances isn't true, the infinite loop doesn't occur.
This what I understood what is happening
viewportInnerSizeChange
event is emitted in useEffect in the useGridDimensions hookviewportInnerSizeChange
listenerWhat's weird is why the
viewportInnerSizeChange
event is emitted after the error boundary is rendered.I'm guessing this useEffect might be causing the error.
Your environment
No response
Search keywords: react router infinite loop loader viewportInnerSizeChange navigate
Order ID: 74777
The text was updated successfully, but these errors were encountered: