diff --git a/package.json b/package.json index ab538a5..e44aebf 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "css-animation": "1.x", "prop-types": "^15.5.6", "rc-animate": "2.x", - "react-is": "^16.7.0" + "react-is": "^16.7.0", + "shallowequal": "^1.1.0" } } diff --git a/src/Collapse.jsx b/src/Collapse.jsx index 0f45bfd..e7b5393 100644 --- a/src/Collapse.jsx +++ b/src/Collapse.jsx @@ -4,6 +4,7 @@ import CollapsePanel from './Panel'; import openAnimationFactory from './openAnimationFactory'; import classNames from 'classnames'; import { isFragment } from 'react-is'; +import shallowEqual from 'shallowequal'; function toArray(activeKey) { let currentActiveKey = activeKey; @@ -42,7 +43,11 @@ class Collapse extends Component { } } - onClickItem(key) { + shouldComponentUpdate(nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + } + + onClickItem = key => { let activeKey = this.state.activeKey; if (this.props.accordion) { activeKey = activeKey[0] === key ? [] : [key]; @@ -60,7 +65,7 @@ class Collapse extends Component { this.setActiveKey(activeKey); } - getNewChild(child, index) { + getNewChild = (child, index) => { if (!child) return null; const activeKey = this.state.activeKey; @@ -77,6 +82,7 @@ class Collapse extends Component { const props = { key, + panelKey: key, header, headerClass, isActive, @@ -85,18 +91,17 @@ class Collapse extends Component { openAnimation: this.state.openAnimation, accordion, children: child.props.children, - onItemClick: disabled ? null : this.onClickItem.bind(this, key), + onItemClick: disabled ? null : this.onClickItem, expandIcon, }; return React.cloneElement(child, props); } - getItems() { + getItems = () => { const { children } = this.props; const childList = isFragment(children) ? children.props.children : children; - - const newChildren = Children.map(childList, this.getNewChild.bind(this)); + const newChildren = Children.map(childList, this.getNewChild); // ref: https://github.com/ant-design/ant-design/issues/13884 if (isFragment(children)) { @@ -110,7 +115,7 @@ class Collapse extends Component { return newChildren; } - setActiveKey(activeKey) { + setActiveKey = activeKey => { if (!('activeKey' in this.props)) { this.setState({ activeKey }); } diff --git a/src/Panel.jsx b/src/Panel.jsx index 7df2b5a..09a8c27 100644 --- a/src/Panel.jsx +++ b/src/Panel.jsx @@ -3,11 +3,18 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import PanelContent from './PanelContent'; import Animate from 'rc-animate'; +import shallowEqual from 'shallowequal'; class CollapsePanel extends Component { + shouldComponentUpdate(nextProps) { + return !shallowEqual(this.props, nextProps); + } + handleItemClick = () => { - if (this.props.onItemClick) { - this.props.onItemClick(); + const { onItemClick, panelKey } = this.props; + + if (typeof onItemClick === 'function') { + onItemClick(panelKey); } } @@ -105,6 +112,7 @@ CollapsePanel.propTypes = { accordion: PropTypes.bool, forceRender: PropTypes.bool, expandIcon: PropTypes.func, + panelKey: PropTypes.any, }; CollapsePanel.defaultProps = { diff --git a/src/PanelContent.jsx b/src/PanelContent.jsx index 8512d90..f53da61 100644 --- a/src/PanelContent.jsx +++ b/src/PanelContent.jsx @@ -1,10 +1,11 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import shallowEqual from 'shallowequal'; class PanelContent extends Component { shouldComponentUpdate(nextProps) { - return this.props.forceRender || this.props.isActive || nextProps.isActive; + return this.props.forceRender || !shallowEqual(this.props, nextProps); } render() {