Your component changes the state. The state is boolean - either on (true) or not (false). Since you're state is switched between two value, you can use a single method (toggle
). Since we check the previous state, it it's better to setState via updater.
You need to bind the method to this
, by using bind in the constructor (method 4) or an arrow function via an instance method (method 5).
Now in the (single) render, you only need to change the text
according to the state of on
:
class Flicker extends React.Component{ state = { on: true }; toggle = () => this.setState(({ on }) => ({ on: !on })); render() { const text = this.state.on ? 'On' : 'Off'; return (<button onClick={this.toggle}>State: {text}</button> ); }}ReactDOM.render(<Flicker />, demo);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script><div id="demo"></div>
Real world example
The button should probably get on
and toggle
via props. Now they are available outside, and the Flicker's only concern is calling toggle
when it's clicked, and changing the text according to on
:
const Toggler = ({ on, toggle }) => (<button onClick={toggle}> State: {on ? 'On' : 'Off'}</button>);class Flicker extends React.Component { state = { on: true }; toggle = () => this.setState(({ on }) => ({ on: !on })); render() { const { on } = this.state; return (<div><Toggler toggle={this.toggle} on={on} /> {on &&'I\'m displayed only when I\'m On' }</div> ); }}ReactDOM.render(<Flicker />, demo);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script><div id="demo"></div>