Skip to content

Commit

Permalink
Merge pull request #29423 from TMisiukiewicz/fix/emoji-menu-rerenders
Browse files Browse the repository at this point in the history
fix: reduce rerendering of EmojiPickerMenu when hovering
  • Loading branch information
mountiny authored Oct 16, 2023
2 parents c29f9af + bfb708b commit 46f0249
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 23 deletions.
9 changes: 3 additions & 6 deletions src/components/EmojiPicker/EmojiPickerMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,12 +457,11 @@ class EmojiPickerMenu extends Component {
return (
<EmojiPickerMenuItem
onPress={(emoji) => this.props.onEmojiSelected(emoji, item)}
onHoverIn={() => this.setState({highlightedIndex: index, isUsingKeyboardMovement: false})}
onHoverOut={() => {
if (this.state.arePointerEventsDisabled) {
onHoverIn={() => {
if (!this.state.isUsingKeyboardMovement) {
return;
}
this.setState({highlightedIndex: -1});
this.setState({isUsingKeyboardMovement: false});
}}
emoji={emojiCode}
onFocus={() => this.setState({highlightedIndex: index})}
Expand All @@ -474,8 +473,6 @@ class EmojiPickerMenu extends Component {
}))
}
isFocused={isEmojiFocused}
isHighlighted={index === this.state.highlightedIndex}
isUsingKeyboardMovement={this.state.isUsingKeyboardMovement}
/>
);
}
Expand Down
37 changes: 20 additions & 17 deletions src/components/EmojiPicker/EmojiPickerMenuItem/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,8 @@ const propTypes = {
/** Handles what to do when the pressable is blurred */
onBlur: PropTypes.func,

/** Whether this menu item is currently highlighted or not */
isHighlighted: PropTypes.bool,

/** Whether this menu item is currently focused or not */
isFocused: PropTypes.bool,

/** Whether the emoji is highlighted by the keyboard/mouse */
isUsingKeyboardMovement: PropTypes.bool,
};

class EmojiPickerMenuItem extends PureComponent {
Expand All @@ -43,6 +37,9 @@ class EmojiPickerMenuItem extends PureComponent {

this.ref = null;
this.focusAndScroll = this.focusAndScroll.bind(this);
this.state = {
isHovered: false,
};
}

componentDidMount() {
Expand Down Expand Up @@ -73,14 +70,26 @@ class EmojiPickerMenuItem extends PureComponent {
shouldUseAutoHitSlop={false}
onPress={() => this.props.onPress(this.props.emoji)}
onPressOut={Browser.isMobile() ? this.props.onHoverOut : undefined}
onHoverIn={this.props.onHoverIn}
onHoverOut={this.props.onHoverOut}
onHoverIn={() => {
if (this.props.onHoverIn) {
this.props.onHoverIn();
}

this.setState({isHovered: true});
}}
onHoverOut={() => {
if (this.props.onHoverOut) {
this.props.onHoverOut();
}

this.setState({isHovered: false});
}}
onFocus={this.props.onFocus}
onBlur={this.props.onBlur}
ref={(ref) => (this.ref = ref)}
style={({pressed}) => [
this.props.isHighlighted && this.props.isUsingKeyboardMovement ? styles.emojiItemKeyboardHighlighted : {},
this.props.isHighlighted && !this.props.isUsingKeyboardMovement ? styles.emojiItemHighlighted : {},
this.props.isFocused ? styles.emojiItemKeyboardHighlighted : {},
this.state.isHovered ? styles.emojiItemHighlighted : {},
Browser.isMobile() && StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)),
styles.emojiItem,
]}
Expand All @@ -95,9 +104,7 @@ class EmojiPickerMenuItem extends PureComponent {

EmojiPickerMenuItem.propTypes = propTypes;
EmojiPickerMenuItem.defaultProps = {
isHighlighted: false,
isFocused: false,
isUsingKeyboardMovement: false,
onHoverIn: () => {},
onHoverOut: () => {},
onFocus: () => {},
Expand All @@ -106,8 +113,4 @@ EmojiPickerMenuItem.defaultProps = {

// Significantly speeds up re-renders of the EmojiPickerMenu's FlatList
// by only re-rendering at most two EmojiPickerMenuItems that are highlighted/un-highlighted per user action.
export default React.memo(
EmojiPickerMenuItem,
(prevProps, nextProps) =>
prevProps.isHighlighted === nextProps.isHighlighted && prevProps.emoji === nextProps.emoji && prevProps.isUsingKeyboardMovement === nextProps.isUsingKeyboardMovement,
);
export default React.memo(EmojiPickerMenuItem, (prevProps, nextProps) => prevProps.isFocused === nextProps.isFocused && prevProps.emoji === nextProps.emoji);

0 comments on commit 46f0249

Please sign in to comment.