message: Reduce number of rerenders of perspective dropdown
diff: @@ -5,7 +5,7 @@ import { CaretDownIcon } from '@patternfly/react-icons';
  import { Perspective } from '@console/plugin-sdk';
  import * as plugins from '../../plugins';
  import { RootState } from '../../redux';
  -import { stateToFlagsObject, FlagsObject } from '../../reducers/features';
  +import { stateToFlagsObject, FlagsObject, featureReducerName } from '../../reducers/features';
  import { getActivePerspective } from '../../reducers/ui';
  import * as UIActions from '../../actions/ui';
  import { history } from '../utils';
  @@ -28,14 +28,12 @@ const NavHeader_: React.FC<NavHeaderProps & StateProps> = ({
  }) => {
  const [isPerspectiveDropdownOpen, setPerspectiveDropdownOpen] = React.useState(false);
  - const togglePerspectiveOpen = () => {
  + const togglePerspectiveOpen = React.useCallback(() => {
  setPerspectiveDropdownOpen(!isPerspectiveDropdownOpen);
  - };
  + }, [isPerspectiveDropdownOpen]);
  - const onPerspectiveSelect = (
  - event: React.MouseEvent<HTMLLinkElement>,
  - perspective: Perspective,
  - ): void => {
  + const onPerspectiveSelect = React.useCallback(
  + (event: React.MouseEvent<HTMLLinkElement>, perspective: Perspective): void => {
  event.preventDefault();
  if (perspective.properties.id !== activePerspective) {
  setActivePerspective(perspective.properties.id);
  @@ -44,9 +42,12 @@ const NavHeader_: React.FC<NavHeaderProps & StateProps> = ({
  setPerspectiveDropdownOpen(false);
  onPerspectiveSelected && onPerspectiveSelected();
  - };
  + },
  + [activePerspective, flags, onPerspectiveSelected, setActivePerspective],
  + );
  - const renderToggle = (icon: React.ReactNode, name: string) => (
  + const renderToggle = React.useCallback(
  + (icon: React.ReactNode, name: string) => (
  <DropdownToggle
  isOpen={isPerspectiveDropdownOpen}
  onToggle={togglePerspectiveOpen}
  @@ -58,9 +59,12 @@ const NavHeader_: React.FC<NavHeaderProps & StateProps> = ({
  {name}
  </Title>
  </DropdownToggle>
  + ),
  + [isPerspectiveDropdownOpen, togglePerspectiveOpen],
  );
  - const getPerspectiveItems = (perspectives: Perspective[]) => {
  + const getPerspectiveItems = React.useCallback(
  + (perspectives: Perspective[]) => {
  return perspectives.map((nextPerspective: Perspective) => (
  <DropdownItem
  key={nextPerspective.properties.id}
  @@ -76,10 +80,15 @@ const NavHeader_: React.FC<NavHeaderProps & StateProps> = ({
  </Title>
  </DropdownItem>
  ));
  - };
  + },
  + [activePerspective, onPerspectiveSelect],
  + );
  - const perspectives = plugins.registry.getPerspectives();
  - const { icon, name } = perspectives.find((p) => p.properties.id === activePerspective).properties;
  + const perspectives = React.useMemo(() => plugins.registry.getPerspectives(), []);
  + const { icon, name } = React.useMemo(
  + () => perspectives.find((p) => p.properties.id === activePerspective).properties,
  + [activePerspective, perspectives],
  + );
  return (
  <div className="oc-nav-header">
  @@ -98,7 +107,13 @@ const mapStateToProps = (state: RootState): StateProps => ({
  flags: stateToFlagsObject(state),
  });
  -export default connect<StateProps, {}, NavHeaderProps>(
  +export default connect<StateProps, {}, NavHeaderProps, RootState>(
  mapStateToProps,
  { setActivePerspective: UIActions.setActivePerspective },
  + null,
  + {
  + areStatesEqual: (next, prev) =>
  + next[featureReducerName] === prev[featureReducerName] &&
  + getActivePerspective(next) === getActivePerspective(prev),
  + },
  )(NavHeader_);
  