-
Notifications
You must be signed in to change notification settings - Fork 3.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
fix(ui): handle React 18 batching for "Submit" button on details page. Fixes #13453 #13593
base: main
Are you sure you want to change the base?
Conversation
The React 18 upgrade in argoproj#13069 introduced a bug on the details page where the "Submit" button is disabled immediately on page load. Specifically, I believe this is happening due to batching changes that affect the following two `useEffect()` calls, which are common to all the details pages modified in this PR: ``` useEffect(() => { (async () => { try { const newEventSource = await services.eventSource.get(name, namespace); setEventSource(newEventSource); setEdited(false); // set back to false setError(null); } catch (err) { setError(err); } })(); }, [name, namespace]); useEffect(() => setEdited(true), [eventSource]); ``` The first runs immediately and invokes `setEventSource(newEventSource)`, which causes the second `useEffect()` call to be fired, since the `eventSource` dependency has changed. Since both are invoking `setEdited()`, this is basically a race condition, since the state of `edited` is going to depend on whether these calls are batched together are fired separately. This PR fixes that by removing the second `useEffect()` call, which eliminates the race condition. Instead, we only call `setEdited(true)` when the editor is modified. Signed-off-by: Mason Malone <[email protected]>
Hmm, so per #13410 (comment) and #13069 (comment), I was planning to revert the React upgrade on That being said, the difference in behavior should be handled regardless, but this may be lower priority as a result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice root cause analysis! We might want to double-check some other places for batching bugs too 🤔 seems like React didn't have any auto-detection for this unfortunately
I left some mostly stylistic comments below, with one behavior correction.
This will have a slight performance hit, which we could solve using
useMemo()
, but I wasn't sure if that was worth it.
Regarding useMemo
, in this case I think it would be worth it, since these are all editor components, so they are latency sensitive to user input
ui/src/app/cluster-workflow-templates/cluster-workflow-template-details.tsx
Outdated
Show resolved
Hide resolved
Signed-off-by: Mason Malone <[email protected]>
Signed-off-by: Mason Malone <[email protected]>
@agilgur5 Thanks for the quick and thorough review! I pushed a couple commits to fix the stylistic issues, switch to |
Fixes #13453
Motivation
The React 18 upgrade in #13069 introduced a bug on the details page where the "Submit" button is disabled immediately on page load. I believe this is happening due to batching changes in React 18 that affect the following two
useEffect()
calls, which are common to all the components modified in this PR:argo-workflows/ui/src/app/event-sources/event-source-details.tsx
Lines 68 to 81 in 729ac17
The first
useEffect()
call runs immediately and invokessetEventSource(newEventSource)
, which causes the seconduseEffect()
call to be fired, since theeventSource
dependency has changed. Since both are invokingsetEdited()
, this is basically a race condition, since the state ofedited
is going to depend on whether these calls are batched together (the behavior in React 18) or fired separately (the old behavior).Modifications
This PR turns the
edited
variable into derived state that dynamically compares objects usingJSON.stringify()
, which eliminates the need foruseEffect(() => setEdited(true), [template])
call, and therefore fixes the race condition.This will have a slight performance hit, which we could solve using
useMemo()
, but I wasn't sure if that was worth it.Verification
Tested locally by editing a template at http://localhost:8081/workflow-templates?namespace=argo:
Screen.Recording.2024-09-12.at.4.53.59.PM.mp4