preactjs / preactjs/preact

different behaviors between Preact and React in Mui-x date pickers

Open
#5,177 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
38.9k
Forks
2.4k
Avg merge
20h 18m
Merged PRs (30d)
35

Description

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 value variable 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 the sectionToUpdateOnNextInvalidDateRef.current has 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!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the minutes-clearing behavior in the linked CodeSandbox, then inspect the referenced useFieldState.ts render around line 424 and the useEffect around line 482. Compare the React and Preact render/effect sequences and identify a change that preserves clearing only the minutes; done means the reproduction matches React behavior without regressing the date picker.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.