web: components: Optimized render of AdvancedSelector + added new tests on it

This commit is contained in:
Alexey Safronov 2019-09-12 17:36:09 +03:00
parent fb116514c5
commit c9433f3781
2 changed files with 67 additions and 16 deletions

View File

@ -1,20 +1,64 @@
import React from 'react';
import { mount } from 'enzyme';
import { mount, shallow } from 'enzyme';
import AdvancedSelector from '.';
const baseProps = {
placeholder: "Search users",
options: [],
isMultiSelect: false,
buttonLabel: "Add members",
onSearchChanged: jest.fn,
onSelect: jest.fn,
onCancel: jest.fn
};
describe('<AdvancedSelector />', () => {
it('renders without error', () => {
const wrapper = mount(
<AdvancedSelector
placeholder="Search users"
onSearchChanged={(e) => console.log(e.target.value)}
options={[]}
isMultiSelect={false}
buttonLabel="Add members"
onSelect={(selectedOptions) => console.log("onSelect", selectedOptions)}
/>
<AdvancedSelector {...baseProps} />
);
expect(wrapper).toExist();
});
it('not re-render test', () => {
const wrapper = shallow(<AdvancedSelector {...baseProps} />).instance();
const shouldUpdate = wrapper.shouldComponentUpdate(wrapper.props, wrapper.state);
expect(shouldUpdate).toBe(false);
});
it('re-render test by options', () => {
const wrapper = shallow(<AdvancedSelector {...baseProps} />).instance();
const shouldUpdate = wrapper.shouldComponentUpdate({
...baseProps,
options: [{key: 1, label: "Example"}]
}, wrapper.state);
expect(shouldUpdate).toBe(true);
});
it('re-render test by groups', () => {
const wrapper = shallow(<AdvancedSelector {...baseProps} />).instance();
const shouldUpdate = wrapper.shouldComponentUpdate({
...baseProps,
groups: [{key: 1, label: "Example"}]
}, wrapper.state);
expect(shouldUpdate).toBe(true);
});
it('re-render test by selectedOptions', () => {
const wrapper = shallow(<AdvancedSelector {...baseProps} />).instance();
const shouldUpdate = wrapper.shouldComponentUpdate({
...baseProps,
selectedOptions: [{key: 1, label: "Example"}]
}, wrapper.state);
expect(shouldUpdate).toBe(true);
});
});

View File

@ -8,9 +8,9 @@ import Link from "../link";
import Checkbox from "../checkbox";
import Button from "../button";
import ComboBox from "../combobox";
import { isArrayEqual } from "../../utils/array";
import findIndex from "lodash/findIndex";
import filter from "lodash/filter";
import isEqual from "lodash/isEqual";
import DropDown from "../drop-down";
import { handleAnyClick } from "../../utils/event";
import isEmpty from "lodash/isEmpty";
@ -119,7 +119,11 @@ class AdvancedSelector extends React.Component {
}
handleClick = e => {
if (this.props.isOpen && !this.ref.current.contains(e.target) && e.target.className.indexOf("option_checkbox") === -1) {
if (
this.props.isOpen &&
!this.ref.current.contains(e.target) &&
e.target.className.indexOf("option_checkbox") === -1
) {
this.props.onCancel && this.props.onCancel();
}
};
@ -128,10 +132,14 @@ class AdvancedSelector extends React.Component {
handleAnyClick(false, this.handleClick);
}
shouldComponentUpdate(nextProps, nextState) {
return !isEqual(this.props, nextProps) || !isEqual(this.state, nextState);
}
componentDidUpdate(prevProps) {
let newState = {};
if (!isArrayEqual(this.props.selectedOptions, prevProps.selectedOptions)) {
if (!isEqual(this.props.selectedOptions, prevProps.selectedOptions)) {
newState = { selectedOptions: this.props.selectedOptions };
}
@ -147,7 +155,7 @@ class AdvancedSelector extends React.Component {
});
}
if (!isArrayEqual(this.props.groups, prevProps.groups)) {
if (!isEqual(this.props.groups, prevProps.groups)) {
const groups = this.convertGroups(this.props.groups);
const currentGroup = this.getCurrentGroup(groups);
newState = Object.assign({}, newState, {
@ -360,9 +368,8 @@ class AdvancedSelector extends React.Component {
};
render() {
const { isDropDown, isOpen, options } = this.props;
const { currentGroup } = this.state;
console.log("AdvancedSelector render()", currentGroup, options);
const { isDropDown, isOpen } = this.props;
//console.log("AdvancedSelector render()");
return isDropDown ? (
<DropDown opened={isOpen}>{this.renderBody()}</DropDown>