Skip to content
This repository has been archived by the owner on Jul 8, 2024. It is now read-only.

Commit

Permalink
Fix: DO-3028 'Maximum update depth...' react error in select (#111)
Browse files Browse the repository at this point in the history
* Memoize downshift props

* Memo more props in combobox and multiselect

* Changelog

* Linting

* Remove excessive memoization for non-ref props
  • Loading branch information
krzysztof-causalens authored May 20, 2024
1 parent 0066692 commit 1d64d6f
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 33 deletions.
6 changes: 5 additions & 1 deletion packages/ui-components/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
title: Changelog
---

## NEXT

- Fixed an issue where select components would sometimes error out with "Maximum update depth..." React error

## 1.9.3

- Fixed a downshift ref warning in `Select` and `DatepickerSelect` components.
Expand All @@ -23,7 +27,7 @@ title: Changelog

- `Chat` component now displays its messages content as `Markdown`.
- `Chat` component now displays next line breaks.
- `Textarea` component when `onComplete` prop is passed adds next line with shift + enter.
- `Textarea` component when `onComplete` prop is passed adds next line with shift + enter.
- Added a new `Markdown` component.
- **Breaking** `Chat` now takes a `active_user` prop, and display user info in each message.
- **Breaking** `Chat` component now only allows users that wrote a message to edit it.
Expand Down
15 changes: 2 additions & 13 deletions packages/ui-components/src/combo-box/combo-box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/
import { autoUpdate, flip, offset, shift, useFloating, useInteractions, useRole } from '@floating-ui/react';
import { UseComboboxReturnValue, UseComboboxStateChangeTypes, useCombobox } from 'downshift';
import { useCallback, useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import ReactDOM from 'react-dom';

import styled from '@darajs/styled-components';
Expand Down Expand Up @@ -272,17 +272,7 @@ function ComboBox(props: ComboBoxProps): JSX.Element {
const role = useRole(context, { role: 'combobox' });
const { getReferenceProps, getFloatingProps } = useInteractions([role]);

const menuProps = getMenuProps();
const setMenuRef = menuProps.ref;
const setFloatingRef = refs.setFloating;

const mergedRefs = useCallback(
(node: HTMLElement | null) => {
setFloatingRef(node);
setMenuRef(node);
},
[setFloatingRef, setMenuRef]
);
const menuProps = useMemo(() => getMenuProps({ ref: refs.setFloating }), [refs.setFloating, getMenuProps]);

return (
<Tooltip content={props.errorMsg} disabled={!props.errorMsg} styling="error">
Expand Down Expand Up @@ -312,7 +302,6 @@ function ComboBox(props: ComboBoxProps): JSX.Element {
<DropdownList
{...menuProps}
{...getFloatingProps()}
ref={mergedRefs}
isOpen={isOpen}
style={{
...floatingStyles,
Expand Down
16 changes: 3 additions & 13 deletions packages/ui-components/src/multiselect/multiselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -331,17 +331,8 @@ function MultiSelect({ maxWidth = '100%', maxRows = 3, ...props }: MultiSelectPr
const role = useRole(context, { role: 'listbox' });
const { getReferenceProps, getFloatingProps } = useInteractions([role]);

const menuProps = getMenuProps();
const setMenuRef = menuProps.ref;
const setFloatingRef = refs.setFloating;

const mergedRefs = useCallback(
(node: HTMLElement | null) => {
setFloatingRef(node);
setMenuRef(node);
},
[setFloatingRef, setMenuRef]
);
const menuProps = useMemo(() => getMenuProps({ ref: refs.setFloating }), [getMenuProps, refs.setFloating]);
const toggleProps = useMemo(() => getToggleButtonProps(), [getToggleButtonProps]);

return (
<Wrapper
Expand Down Expand Up @@ -381,7 +372,7 @@ function MultiSelect({ maxWidth = '100%', maxRows = 3, ...props }: MultiSelectPr
style={{ flex: '1 1 5ch' }}
/>
</TagWrapper>
<ChevronButton {...getToggleButtonProps()}>
<ChevronButton {...toggleProps}>
<Chevron disabled={props.disabled} isOpen={isOpen} />
</ChevronButton>
</InputWrapper>
Expand All @@ -390,7 +381,6 @@ function MultiSelect({ maxWidth = '100%', maxRows = 3, ...props }: MultiSelectPr
<DropdownList
{...menuProps}
{...getFloatingProps()}
ref={mergedRefs}
isOpen={isOpen}
style={{
...floatingStyles,
Expand Down
14 changes: 8 additions & 6 deletions packages/ui-components/src/select/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,21 @@ function Select(props: SelectProps): JSX.Element {
const role = useRole(context, { role: 'listbox' });
const { getReferenceProps, getFloatingProps } = useInteractions([role]);

const menuProps = getMenuProps();
const setMenuRef = menuProps.ref;
const setFloatingRef = refs.setFloating;
const { dropdownRef } = props;

const mergedDropdownRef = React.useCallback(
(node: HTMLElement | null) => {
setFloatingRef(node);
setMenuRef(node);
dropdownRef?.(node);
},
[setFloatingRef, setMenuRef, dropdownRef]
[setFloatingRef, dropdownRef]
);
const menuProps = React.useMemo(() => getMenuProps({ ref: mergedDropdownRef }), [mergedDropdownRef, getMenuProps]);

const toggleButtonProps = React.useMemo(
() => getToggleButtonProps({ disabled: props.disabled, ref: refs.setReference }),
[props.disabled, refs.setReference, getToggleButtonProps]
);

return (
Expand All @@ -218,7 +221,7 @@ function Select(props: SelectProps): JSX.Element {
<SelectButton
disabled={props.disabled}
isOpen={isOpen}
{...getToggleButtonProps({ disabled: props.disabled, ref: refs.setReference })}
{...toggleButtonProps}
{...getReferenceProps()}
type="button"
>
Expand All @@ -233,7 +236,6 @@ function Select(props: SelectProps): JSX.Element {
<DropdownList
{...menuProps}
{...getFloatingProps()}
ref={mergedDropdownRef}
className={`${(menuProps?.className as string) ?? ''} ${props.itemClass}`}
isOpen={isOpen}
maxItems={props.maxItems}
Expand Down

0 comments on commit 1d64d6f

Please sign in to comment.