Skip to content

Instantly share code, notes, and snippets.

@nahumzs
Last active March 14, 2018 22:31
Show Gist options
  • Save nahumzs/fb1148778cd916ed00c261a41edef322 to your computer and use it in GitHub Desktop.
Save nahumzs/fb1148778cd916ed00c261a41edef322 to your computer and use it in GitHub Desktop.
export default class Collapsible extends Component {
state = {
// this state will be use by the uncontrolled component
startCollapsed: this.props.startCollapsed || true,
}
// How to detect if it's controlled or not
isControlled() {
return typeof this.props.isCollapsed !== "undefined";
}
onClick() {
// even if it is uncontrolled the consuming app
// might be interested to know about this change
if (typeof this.props.onClick === "function") {
this.props.onClick();
}
if (!this.isControlled()) {
this.setState({ startCollapsed: !this.state.startCollapsed });
}
}
renderContent() {
const {children} = this.props;
// Decide base on the props what to do.
// DO NOT try to sync the state, that might open the door for πŸ›πŸœπŸœπŸœ (BUGS)
if (this.isControlled()) {
return this.props.isCollapsed ? null : children;
}
return this.state.startCollapsed ? null : children;
}
render() {
const {label, children} = this.props;
return (
<div className="collapsible">
<div>{label}<button onClick={() => this.onClick()}>toggle</button></div>
<div>{this.renderContent()}</div>
</div>
)
}
}
// Uncontrolled
<Toggle label="Hybrid uncontrolled component 😎">
πŸ¦„πŸŽ‰βš‘οΈπŸŒΆπŸΏπŸŒ΄
</Toggle>
// Controlled
<Toggle
onClick={() => this.setState({ isCollapsed: !this.state.isCollapsed})}
isCollapsed={this.state.isCollapsed}
label="Hybrid controlled component 😎"
>
πŸŽπŸš€πŸ™€πŸ’―
</Toggle>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment