Skip to content

Fix remaining React strict mode issues #4564

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

Merged
merged 56 commits into from
Jun 1, 2023
Merged

Fix remaining React strict mode issues #4564

merged 56 commits into from
Jun 1, 2023

Conversation

devongovett
Copy link
Member

@devongovett devongovett commented May 22, 2023

Closes #779. Includes and closes #4145, closes #4035, closes #4012, closes #4005, closes #3835, closes #3104

Note for reviewers: it may be helpful to review commit by commit. I've tried to separate the changes and included notes on each commit with details about the changes.

This fixes the remaining failing tests in React strict mode. Most of them were related to Virtualizer (the first two commits brought the failures from 745 to 157). Virtualizer is fixed by queuing updates to occur in a layout effect rather than updating during render, or in a raf. This way when double renders occur, we don't have two separate instances of the underlying Virtualizer class competing with one another.

157
ReusableView can be mutated, so we need to pass the layoutInfo/content at the time we render to the JSX element rather than reading directly

122
We used to focus the collection itself when the focused item went out of view, but we don't need this anymore because we use persistedKeys to ensure the focused item is always in the DOM. In strict mode this was causing some weird behavior due to ordering of the useEffects. We also need to ensure that when a DOM node is reused for a different item that we do actually move focus.
Escape should take you back to the original drag target, and should not affect the focusedKey of the target list.
Simplified versions of #4005 with minimal changes. Uses state instead of refs to store previous values and avoid flicker due to effect. Removes parsed ref, which has been unnecessary since 10e57d4.
Fixes sliders and color components (alternative to #4012).
Incorporates #4035
Doing this in render was actually wrong anyway because if you had the tabs in a controlled state, it would fire onSelectionChange during render which would result in react erroring about updating a different component while another was rendering. Doing it in useEffect is the right time.
@rspbot
Copy link

rspbot commented May 31, 2023

snowystinger
snowystinger previously approved these changes May 31, 2023
@rspbot
Copy link

rspbot commented May 31, 2023

@rspbot
Copy link

rspbot commented Jun 1, 2023

@adobe adobe deleted a comment from rspbot Jun 1, 2023
@rspbot
Copy link

rspbot commented Jun 1, 2023

@rspbot
Copy link

rspbot commented Jun 1, 2023

## API Changes

unknown top level export { type: 'identifier', name: 'Column' }
unknown top level export { type: 'identifier', name: 'Column' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
undefined already in set

@react-aria/utils

useEffectEvent

-
+useDeepMemo<T> {
+  value: T
+  isEqual: (T, T) => boolean
+  returnVal: undefined
+}

@react-aria/virtualizer

Virtualizer

 Virtualizer<T extends {}, V> {
+  autoFocus?: boolean
   children: (string, {}) => V
   collection: Collection<{}>
   focusedKey?: Key
   isLoading?: boolean
   onLoadMore?: () => void
   renderWrapper?: (ReusableView<{}, V> | null, ReusableView<{}, V>, Array<ReusableView<{}, V>>, (Array<ReusableView<{}, V>>) => Array<ReactElement>) => ReactElement
   scrollDirection?: 'horizontal' | 'vertical' | 'both'
   scrollToItem?: (Key) => void
   shouldUseVirtualFocus?: boolean
   sizeToFit?: 'width' | 'height'
   transitionDuration?: number
 }
 

useVirtualizerItem

changed by:

  • VirtualizerItemOptions
-useVirtualizerItem<T extends {}, V> {
-  options: VirtualizerItemOptions<T, V>
-  returnVal: undefined
-}
+

VirtualizerItem

-VirtualizerItem<T extends {}, V> {
-  className?: string
-  parent?: ReusableView<{}, V>
-  reusableView: ReusableView<{}, V>
-}
+

VirtualizerItemOptions

-
+VirtualizerItemOptions {
+  layoutInfo: LayoutInfo
+  ref: RefObject<HTMLElement>
+  virtualizer: IVirtualizer
+}

it changed:

  • useVirtualizerItem

undefined

-
+useVirtualizerItem {
+  options: VirtualizerItemOptions
+  returnVal: undefined
+}

undefined

-
+VirtualizerItem {
+  children: ReactNode
+  className?: string
+  parent?: LayoutInfo
+}

@react-spectrum/listbox

ListBox

 useListBoxLayout<T> {
   state: ListState<T>
+  isLoading: boolean
   returnVal: undefined
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

useTabsListState onSelectionChange called during render Add tests for components in React StrictMode
5 participants