Advanced React Component Patterns - 2
by,
Shakthishree
Simple Toggle Component
import React, {Component} from 'react';
import Switch from './switch';
export default class Toggle extends Component {
state = {on: false};
toggle = () => {
this.setState(({on}) => ({on: !on}));
this.props.onToggle(!this.state.on);
};
render() {
return (
<div>
<Switch
on={this.state.on}
onClick={this.toggle}
/>
<div>
{this.state.on ? 'on' : 'off'}
</div>
</div>
);
}
}
import React, {Component} from 'react';
import Toggle from './toggle';
export default class User extends Component {
onToggle = ( on ) => {
console.log( on ? 'On' : 'Off' );
};
render() {
return (
<Toggle onToggle = { this.onToggle } />
)
}
}
Flexible Toggle Component
Compound Component
export default class Toggle extends Component {
state = {on: false};
static On = ({on}) =>
(on ? <div>On</div> : null);
static Off = ({on}) =>
(on ? null : <div>Off</div>);
static Button = ({on, toggle}) =>
<Switch on={on} onClick={toggle} />;
toggle = () => {
this.setState(({on}) => ({on: !on}));
this.props.onToggle(!this.state.on);
};
render() {
return (
React.Children.map(
this.props.children, child =>
React.cloneElement(child, {
on: this.state.on,
toggle: this.toggle,
});
);
);
}
}
export default class User extends Component {
onToggle = on => {
console.log(on ? 'on' : 'false' );
};
render() {
return (
<Toggle onToggle={this.onToggle}>
<Toggle.Button />
<Toggle.Off />
<Toggle.On />
</Toggle>
);
}
}
React Context API
const ToggleContext = React.createContext();
static On = ({children}) =>
<ToggleContext.Consumer>
{({on, children}) => {
return on ? children : null;}}
</ToggleContext.Consumer>;
static Off = ({children}) =>
<ToggleContext.Consumer>
{({on, children}) => {
return on ? null : children;}}
</ToggleContext.Consumer>;
static Button = ({children}) =>
<ToggleContext.Consumer>
{({on, toggle}) =>
<Switch on={on} onClick={toggle} />}
</ToggleContext.Consumer>;
render() {
return (
<ToggleContext.Provider
value={{on: this.state.on,
toggle: this.toggle}}>
{this.props.children}
</ToggleContext.Provider>);}
export default class User extends Component {
onToggle = on => {
console.log(on ? 'on' : 'false' );
};
render() {
return (
<Toggle onToggle={this.onToggle}>
<div style={{
height: '40px',
width: '60px',
backgroundColor: '#7eb36d',
marginTop: '10px',
border: '1px solid grey',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}>
<Toggle.Button />
</div>
<Toggle.Off />
<Toggle.On />
</Toggle>
);
}
}
Render Props
import React, {Component} from 'react';
import Switch from './switch';
class Toggle extends Component {
state = {on: false};
toggle = () => {
this.setState({on: !this.state.on});
this.props.onToggle(this.state.on);
};
render(){
return(
this.props.children({
on: this.state.on,
toggle: this.toggle,
})
)
}
}
import React, {Component} from 'react';
import './switch';
export default class User extends Component {
onToggle = on => {
console.log(on ? 'on' : 'false' );
};
render() {
return (
<Toggle
onToggle={this.onToggle}
>
{({on, toggle}) =>
<div>
{on ? 'on' : 'off'}
</div>
<Switch on={on} onClick={toggle} />
}
</Toggle>
);
}
}
Text