Skip to content

Instantly share code, notes, and snippets.

@hmtri1011
Last active December 25, 2018 04:15
Show Gist options
  • Save hmtri1011/6fb686ca8230e222302d94a14af2a899 to your computer and use it in GitHub Desktop.
Save hmtri1011/6fb686ca8230e222302d94a14af2a899 to your computer and use it in GitHub Desktop.
Dummy Tab Component which is allow its items not unmount after switching
import React, { Component } from 'react'
class CompA extends Component {
state = {
text: 'This is Component A'
}
componentDidMount() {
console.log('ahihi comp a did mount')
}
componentDidUpdate() {
console.log('ahihi comp a did update')
}
componentWillUnmount() {
console.log('ahihi comp a unmount')
}
_changeText = () => {
this.setState(() => ({
text: 'This is Component A after text changed'
}))
}
render() {
const { style } = this.props
const { text } = this.state
return (
<div style={style}>
<h2>{text}</h2>
<button onClick={this._changeText}>Change Component A Text</button>
</div>
)
}
}
class CompB extends Component {
state = {
text: 'This is Component B'
}
componentDidMount() {
console.log('ahihi comp b did mount')
}
componentDidUpdate() {
console.log('ahihi comp b did update')
}
componentWillUnmount() {
console.log('ahihi comp b unmount')
}
_changeText = () => {
this.setState(() => ({
text: 'This is Component B after text changed'
}))
}
render() {
const { style } = this.props
const { text } = this.state
return (
<div style={style}>
<h2>{text}</h2>
<button onClick={this._changeText}>Change Component B Text</button>
</div>
)
}
}
class CompC extends Component {
state = {
text: 'This is Component C'
}
componentDidMount() {
console.log('ahihi comp c did mount')
}
componentDidUpdate() {
console.log('ahihi comp c did update')
}
componentWillUnmount() {
console.log('ahihi comp c unmount')
}
_changeText = () => {
this.setState(() => ({
text: 'This is Component C after text changed'
}))
}
render() {
const { style } = this.props
const { text } = this.state
return (
<div style={style}>
<h2>{text}</h2>
<button onClick={this._changeText}>Change Component C Text</button>
</div>
)
}
}
class TabItem extends Component {
render() {
const { id, onChangeTab } = this.props
return <button onClick={() => onChangeTab(id)}>{`Tab Header ${id}`}</button>
}
}
class Tab extends Component {
state = {
selectedId: 0
}
alreadyRenderedChilds = [
{
id: 0,
component: <CompA />
}
]
_handleSelectTab = (id, Component) => () => {
const isAddedChild = this.alreadyRenderedChilds.find(
child => child.id === id
)
if (!isAddedChild) {
this.alreadyRenderedChilds.push({
id,
component: <Component />
})
}
this.setState(() => ({
selectedId: id
}))
}
render() {
const { selectedId } = this.state
const hidden = {
display: 'none'
}
return (
<div>
<div>
<TabItem id={0} onChangeTab={this._handleSelectTab(0, CompA)} />
<TabItem id={1} onChangeTab={this._handleSelectTab(1, CompB)} />
<TabItem id={2} onChangeTab={this._handleSelectTab(2, CompC)} />
</div>
{this.alreadyRenderedChilds.map(child =>
React.cloneElement(child.component, {
style: selectedId === child.id ? {} : hidden,
key: child.id
})
)}
</div>
)
}
}
export default Tab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment