Skip to content

Commit

Permalink
refactor(EuiSelectableList): add listRowRerender count tracker to ens…
Browse files Browse the repository at this point in the history
…ure rerenders via key
  • Loading branch information
mgadewoll committed May 10, 2024
1 parent 8f362e7 commit b98f015
Showing 1 changed file with 54 additions and 23 deletions.
77 changes: 54 additions & 23 deletions src/components/selectable/selectable_list/selectable_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ export class EuiSelectableList<T> extends Component<
};

private animationFrameId: number | undefined;
// counter for tracking list renders and ensuring rerenders
private listRowRerender = 0;

constructor(props: EuiSelectableListProps<T>) {
super(props);
Expand Down Expand Up @@ -258,9 +260,47 @@ export class EuiSelectableList<T> extends Component<
}
};

shouldComponentUpdate(
nextProps: Readonly<EuiSelectableListProps<T>>
): boolean {
const {
allowExclusions,
showIcons,
paddingSize,
textWrap,
onFocusBadge,
searchable,
} = this.props;

// using shouldComponentUpdate to determine needed rerender before actual rerender
// without needing state updates or lagging behind on updates
if (
nextProps.allowExclusions !== allowExclusions ||
nextProps.showIcons !== showIcons ||
nextProps.paddingSize !== paddingSize ||
nextProps.textWrap !== textWrap ||
nextProps.onFocusBadge !== onFocusBadge ||
nextProps.searchable !== searchable
) {
this.listRowRerender += 1;
}

return true;
}

componentDidUpdate(prevProps: EuiSelectableListProps<T>) {
const { isVirtualized, activeOptionIndex, visibleOptions, options } =
this.props;
const {
isVirtualized,
activeOptionIndex,
visibleOptions,
options,
allowExclusions,
showIcons,
paddingSize,
textWrap,
onFocusBadge,
searchable,
} = this.props;

if (prevProps.activeOptionIndex !== activeOptionIndex) {
const { makeOptionId } = this.props;
Expand Down Expand Up @@ -300,15 +340,17 @@ export class EuiSelectableList<T> extends Component<
}

// ensure that ListRow updates based on item props
if (
isVirtualized &&
(prevProps.showIcons !== this.props.showIcons ||
prevProps.paddingSize !== this.props.paddingSize ||
prevProps.textWrap !== this.props.textWrap ||
prevProps.onFocusBadge !== this.props.onFocusBadge ||
prevProps.searchable !== this.props.searchable)
) {
this.forceVirtualizedListRowRerender();
if (isVirtualized) {
if (
prevProps.allowExclusions !== allowExclusions ||
prevProps.showIcons !== showIcons ||
prevProps.paddingSize !== paddingSize ||
prevProps.textWrap !== textWrap ||
prevProps.onFocusBadge !== onFocusBadge ||
prevProps.searchable !== searchable
) {
this.forceVirtualizedListRowRerender();
}
}
}

Expand Down Expand Up @@ -664,15 +706,6 @@ export class EuiSelectableList<T> extends Component<
...rest
} = this.props;

const itemProps = {
allowExclusions,
onFocusBadge,
showIcons,
paddingSize,
searchable,
textWrap,
};

const heightIsFull = forcedHeight === 'full';

const classes = classNames(
Expand All @@ -699,11 +732,9 @@ export class EuiSelectableList<T> extends Component<
React.createElement(
this.ListRow,
{
key: index,
key: `${index}-${this.listRowRerender}`,
data: this.state.optionArray,
index,
// pass additional props to ensure rerender on list item prop updates
...itemProps,
},
null
)
Expand Down

0 comments on commit b98f015

Please sign in to comment.