Skip to content

Commit 738d9d8

Browse files
committed
fix(react): Fix lifecycle for react 16.3 or newer
BREAKING CHANGE: Minimum compatible version of react is now 16.3
1 parent 0c0b52f commit 738d9d8

File tree

3 files changed

+24
-20
lines changed

3 files changed

+24
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ An accessible and easy tab component for ReactJS.
44

55
http://reactcommunity.org/react-tabs/
66

7-
> Supports React 0.14.9+, 15.3+ and 16+
7+
> Supports React 16.3.0 or newer
88
99
<ins><blockquote class="rich-diff-level-zero"> <p class="rich-diff-level-one">react-tabs was tested on real mobile devices and browsers with<br>
1010
<img src="http://reactcommunity.org/react-tabs/7215e21fc3d710d2257900135d6fc03c.svg" height="50" alt="Browserstack">

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"react-component"
5050
],
5151
"peerDependencies": {
52-
"react": "^0.14.9 || ^15.3.0 || ^16.0.0"
52+
"react": "^16.3.0"
5353
},
5454
"devDependencies": {
5555
"@babel/cli": "^7.0.0",

src/components/Tabs.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import {
88
import UncontrolledTabs from './UncontrolledTabs';
99
import { getTabsCount } from '../helpers/count';
1010

11+
const MODE_CONTROLLED = 0;
12+
const MODE_UNCONTROLLED = 1;
13+
1114
export default class Tabs extends Component {
1215
static defaultProps = {
1316
defaultFocus: false,
@@ -40,28 +43,17 @@ export default class Tabs extends Component {
4043
this.state = Tabs.copyPropsToState(this.props, {}, props.defaultFocus);
4144
}
4245

43-
componentWillReceiveProps(newProps) {
44-
if (
45-
process.env.NODE_ENV !== 'production' &&
46-
Tabs.inUncontrolledMode(newProps) !== Tabs.inUncontrolledMode(this.props)
47-
) {
48-
throw new Error(
49-
`Switching between controlled mode (by using \`selectedIndex\`) and uncontrolled mode is not supported in \`Tabs\`.
50-
For more information about controlled and uncontrolled mode of react-tabs see the README.`,
51-
);
52-
}
53-
// Use a transactional update to prevent race conditions
54-
// when reading the state in copyPropsToState
55-
// See https://github.com/reactjs/react-tabs/issues/51
56-
this.setState(state => Tabs.copyPropsToState(newProps, state));
46+
static getDerivedStateFromProps(props, state) {
47+
return Tabs.copyPropsToState(props, state);
5748
}
5849

59-
static inUncontrolledMode(props) {
60-
return props.selectedIndex === null;
50+
static getModeFromProps(props) {
51+
return props.selectedIndex === null ? MODE_UNCONTROLLED : MODE_CONTROLLED;
6152
}
6253

6354
handleSelected = (index, last, event) => {
6455
const { onSelect } = this.props;
56+
const { mode } = this.state;
6557

6658
// Call change event handler
6759
if (typeof onSelect === 'function') {
@@ -74,7 +66,7 @@ For more information about controlled and uncontrolled mode of react-tabs see th
7466
focus: event.type === 'keydown',
7567
};
7668

77-
if (Tabs.inUncontrolledMode(this.props)) {
69+
if (mode === MODE_UNCONTROLLED) {
7870
// Update selected index
7971
state.selectedIndex = index;
8072
}
@@ -85,11 +77,23 @@ For more information about controlled and uncontrolled mode of react-tabs see th
8577
// preserve the existing selectedIndex from state.
8678
// If the state has not selectedIndex, default to the defaultIndex or 0
8779
static copyPropsToState(props, state, focus = false) {
80+
if (
81+
process.env.NODE_ENV !== 'production' &&
82+
state.mode !== undefined &&
83+
state.mode !== Tabs.getModeFromProps(props)
84+
) {
85+
throw new Error(
86+
`Switching between controlled mode (by using \`selectedIndex\`) and uncontrolled mode is not supported in \`Tabs\`.
87+
For more information about controlled and uncontrolled mode of react-tabs see the README.`,
88+
);
89+
}
90+
8891
const newState = {
8992
focus,
93+
mode: Tabs.getModeFromProps(props),
9094
};
9195

92-
if (Tabs.inUncontrolledMode(props)) {
96+
if (newState.mode === MODE_UNCONTROLLED) {
9397
const maxTabIndex = getTabsCount(props.children) - 1;
9498
let selectedIndex = null;
9599

0 commit comments

Comments
 (0)