Repository navigation
Replies: 4 comments
|
Thanks for the detailed report! I dug into the reproduction and this seems to be caused by the delayed controlled update (as you correctly point out) rather than Preact’s render ordering. MUI clears its pending section ref before the setTimeout(0) update arrives. With the delayed update I see the whole field cleared in both React and Preact. With a synchronous update, both only clear the minutes. Could you share a React reproduction using the exact same onChange? For MUI X 9, a separate reproduction would also help since it uses a different field DOM structure. I'm not sure whether we should fix this in Preact as this code looks brittle 😅 a proper solution there could be to:
We have seen issues with the fact that we batch state-updates within a micro-task which would execute before a tick ( |
|
Hi @JoviDeCroock, first of all, thank you for the quick reply and analysis! 😃 I have to apologize to begin with! 😔 My reproduction had a silly I see now that without the timeout, the reproduction works in Preact too, even though it still fails in my actual project. At this point, I suspect an external re-render in my code is triggering the unconditioned Since I originally mentioned finding 3 issues in the same component, let's move on to the next one. 😄 https://codesandbox.io/p/devbox/8nptwq In my original reproduction, I was only using the As a final note, I just want to clarify that I am not here looking for solutions 😅. I've already managed to workaround/patch these behaviors in my project (honestly, I consider these specific parts of the picker to be quite fragile and believe MUI maintainers should rewrite them), but my priority right now is Preact rather than MUI-X, so my goal here is simply to bring these findings to your attention. I'll leave it to you to triage and see if they highlight any small differences between Preact and React that might be worth handling to improve out-of-the-box compatibility. PS: I know we can't aim for 100% compatibility, but I wanted to share these just in case they point to something interesting for the Preact team! 😄 |
|
@JoviDeCroock just a little ping to know whether you had a chance to check the second issue. As stated, I don't need a fix or a workaround, but I am still really curious to see your triage and findings about that issue! 😅 |
|
It seems related to the contentEditable and innerHTML injection. I don't think we should support that |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
So, I have found 3 different behaviors between React and Preact in a single component (react-mui-x datepickers)! :)
Please note: I used the 8.x branch of react mui-x, but the issue is still present also in the latest 9.x.
In my opinion, these are mostly due to fragile implementations, leveraging timeouts, imperatively modifying the DOM, and similar techniques, but since this is one of the most popular React UI libraries, I thought it was worth bringing to your attention.
Let's start with the first one. The component is quite complex, but after spending some time debugging, I've narrowed down the key points. I can provide further details along the way if needed.
Here you can find a reproduction.
https://codesandbox.io/p/devbox/8nptwq
Click on the minutes, they will get focus and become selected. Now press backspace, and you will see that the entire time is cleared, while the expected (React) behavior is to only clear the minutes.
You can use this line for breakpoints and monitoring of the main render of the component https://github.com/mui/mui-x/blob/7b07ee868c8952879cabca36f1b72a4083b2bbe3/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts#L424
This useEffect is also an active part of the issue. https://github.com/mui/mui-x/blob/7b07ee868c8952879cabca36f1b72a4083b2bbe3/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts#L482
Now, what happens: when you clear the minutes, the
valuevariable in the aforementioned render, on React will be already set to null (since the date w/o minutes is now invalid), the first condition is true and thesectionToUpdateOnNextInvalidDateRef.currenthas a value because the useEffect in my second permalink that clears that ref hasn't been executed yet.On Preact, on the contrary, the main render is executed with value !== null so we won't enter the first if block, then the clear-reference useEffect runs , and afterwards there is a second render that this time enters the if block, but since the ref is now cleared, it doesn't act as it should.
Summing up, there is a different rendering behavior between React and Preact, in this case, and this is causing an issue.
I apologize if this report is a bit dense; I wanted to keep it as concise and schematic as possible. Let me know your thoughts, and I'd be happy to follow up from here!
Thank you!
All reactions