Skip to content

Commit

Permalink
[fixed] Issue when conditionally rendering Tab/TabPanel
Browse files Browse the repository at this point in the history
closes reactjs#37
  • Loading branch information
mzabriskie committed Oct 22, 2015
1 parent 2742248 commit e05a9ec
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
53 changes: 53 additions & 0 deletions examples/conditional/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Tab, Tabs, TabList, TabPanel } from '../../lib/main';

const App = React.createClass({
getInitialState() {
return {
showA: true,
showB: true,
showC: true
};
},

handleCheckClicked(e) {
const state = {};
state[e.target.name] = e.target.checked;
this.setState(state);
},

render() {
return (
<div style={{padding: 50}}>
<p>
<label>
<input type="checkbox" checked={this.state.showA} name="showA" onChange={this.handleCheckClicked}/>
Show A
</label><br/>
<label>
<input type="checkbox" checked={this.state.showB} name="showB" onChange={this.handleCheckClicked}/>
Show B
</label><br/>
<label>
<input type="checkbox" checked={this.state.showC} name="showC" onChange={this.handleCheckClicked}/>
Show C
</label><br/>
</p>
<Tabs>
<TabList>
{ this.state.showA && <Tab>Tab A</Tab> }
{ this.state.showB && <Tab>Tab B</Tab> }
{ this.state.showC && <Tab>Tab C</Tab> }
</TabList>
{ this.state.showA && <TabPanel>This is tab A</TabPanel> }
{ this.state.showB && <TabPanel>This is tab B</TabPanel> }
{ this.state.showC && <TabPanel>This is tab C</TabPanel> }
</Tabs>
</div>
);
}
});

ReactDOM.render(<App/>, document.getElementById('example'));

8 changes: 8 additions & 0 deletions examples/conditional/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!doctype html>
<meta charset="utf-8"/>
<title>React Tabs</title>
<body>
<div id="example"></div>
<script src="../__build__/shared.js"></script>
<script src="../__build__/conditional.js"></script>

12 changes: 12 additions & 0 deletions lib/components/Tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ module.exports = React.createClass({

// Map children to dynamically setup refs
return React.Children.map(children, (child) => {
// null happens when conditionally rendering TabPanel/Tab
// see https://github.com/rackt/react-tabs/issues/37
if (child === null) {
return null;
}

let result = null;

// Clone TabList and Tab components to have refs
Expand All @@ -222,6 +228,12 @@ module.exports = React.createClass({
result = cloneElement(child, {
ref: 'tablist',
children: React.Children.map(child.props.children, (tab) => {
// null happens when conditionally rendering TabPanel/Tab
// see https://github.com/rackt/react-tabs/issues/37
if (tab === null) {
return null;
}

const ref = 'tabs-' + index;
const id = tabIds[index];
const panelId = panelIds[index];
Expand Down
20 changes: 20 additions & 0 deletions lib/components/__tests__/Tabs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,5 +236,25 @@ describe('react-tabs', function() {

ok(!error);
});

it('should gracefully render null', function() {
let error = false;
try {
TestUtils.renderIntoDocument(
<Tabs>
<TabList>
<Tab>Tab A</Tab>
{ false && <Tab>Tab B</Tab> }
</TabList>
<TabPanel>Content A</TabPanel>
{ false && <TabPanel>Content B</TabPanel> }
</Tabs>
);
} catch (e) {
error = true;
}

ok(!error);
});
});
});
12 changes: 12 additions & 0 deletions lib/helpers/childrenPropType.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ module.exports = function childrenPropTypes(props, propName) {
const children = props[propName];

React.Children.forEach(children, (child) => {
// null happens when conditionally rendering TabPanel/Tab
// see https://github.com/rackt/react-tabs/issues/37
if (child === null) {
return;
}

if (child.type === TabList) {
React.Children.forEach(child.props.children, (c) => {
// null happens when conditionally rendering TabPanel/Tab
// see https://github.com/rackt/react-tabs/issues/37
if (c === null) {
return;
}

if (c.type === Tab) {
tabsCount++;
} else {
Expand Down

0 comments on commit e05a9ec

Please sign in to comment.