Allow their state to be driven from props, as seen below.
<input
placeholder="email"
onChange={e =>
this.setState({
email: e.target.value
})
}
value={this.state.email}
/>
It can work, we can type in it, but we can't control its internal state. For example, we can't clear the value.
class App extends Component {
state = {email: ''};
render() {
return (
<input
placeholder="email"
onChange={e =>
this.setState({
email: e.target.value
})
}
/>
);
}
}
Now reading the following code below, we have control over the component's value.
class App extends Component {
state = {email: ''};
clearValue = () => {
this.setState({email: ''});
};
render() {
return (
<div>
<input
placeholder="email"
onChange={e =>
this.setState({
email: e.target.value
})
}
value={this.state.email}
/>
<button onClick={this.clearValue}> clear </button>
</div>
);
}
}
class App extends React.Component {
render() {
return (
<Tabs
tabs={[
{id: 'home', label: 'Home'},
{id: 'contact', label: 'Contact'},
{id: 'about', label: 'About'}
]}
/>
);
}
}
const Tab = ({label, active, onSelect}) => (
<div
style={{
backgroundColor: active ? 'purple' : 'white'
}}
onClick={onSelect}
>
{label}
</div>
);
First, we can add a value
prop. This prop will tell the Tabs component that we want to control the current value from the outside.
<Tabs
value="contact"
tabs={[
{id: 'home', label: 'Home'},
{id: 'contact', label: 'Contact'},
{id: 'about', label: 'About'}
]}
/>
class App extends React.Component {
state = {selectedTab: 'contact'};
selectTab = tab => this.setState({selectedTab: tab.id});
render() {
return (
<Tabs
onChange={tab => this.selectTab(tab)}
value={this.state.selectedTab}
tabs={[
{id: 'home', label: 'Home'},
{id: 'contact', label: 'Contact'},
{id: 'about', label: 'About'}
]}
/>
);
}
}
class Tabs extends React.Component {
state = {
selectedTab:
this.props.value || this.props.defaultValue || this.props.tabs[0].id
};
selectTab = tab => {
const {onChange} = this.props;
let isControlled = onChange && typeof onChange === 'function';
isControlled ? onChange(tab) : this.setState({selectedTab: tab.id});
};
render() {
const {tabs, value} = this.props;
return tabs.map(tab => (
<Tab
id={tab.id}
label={tab.label}
onSelect={() => this.selectTab(tab)}
active={tab.id === (value || this.state.selectedTab)}
/>
));
}
}
<Tabs
onChange={tab => this.setState({selectedTab: tab})}
value={this.state.value}
tabs={[
{id: 'home', label: 'Home'},
{id: 'contact', label: 'Contact'},
{id: 'about', label: 'About'}
]}
/>
<Tabs
tabs={[
{id: 'home', label: 'Home'},
{id: 'contact', label: 'Contact'},
{id: 'about', label: 'About'}
]}
/>