Making calculator app in React. setState is not working

时间:2019-04-08 13:20:36

标签: reactjs state

I'm making a calculator app in React. Here I have App component and Button component. When I click a button, despite I setState with parameter (event.target.getAttribute('data-number'), it console logs different number from the button's attribute.

When I click button with 'data-number=1', state 'result' is set to "0". Then I click button with 'data-number=7', state 'result' is set to '1'. I wonder what is happening and how to fix this problem.

class App extends React.Component {
    state = { result: 0 };

    currentNumber = (number) => {
        this.setState({ result: number })
        console.log("Number from Button", number); // 1
        console.log("Current number in state", this.state.result); // 0
    }

    render() {
        return (
            <div>
                <Button onClick = {this.currentNumber} />
            </div>
        );
    }
}
class Button extends React.Component {

    render() {
        return (
            <ul>
                <li><button data-number="1" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>1</button></li>
            </ul>

2 个答案:

答案 0 :(得分:2)

The call to setState is async, meaning state is not updated right away. You can pass a callback that gets run after state updates:

this.setState({ result: number }, () => {
        console.log("Number from Button", number); // 1
        console.log("Current number in state", this.state.result); // 1
})

答案 1 :(得分:0)

As @Smarticles101 mentioned, setState is async. Here's your code working properly.

Notice the difference between the callback logs and the outside callback logs. Checkout these docs on setState for more information.

class App extends React.Component {
    state = { result: 0 };

    currentNumber = (number) => {
        this.setState({ result: number }, () => {
          console.log("Callback, number: ", number);
          console.log("Callback, result: ", this.state.result);
        })
        
        console.log("Outside callback, number: ", number);
        console.log("Outside callback, result: ", this.state.result);
        
    }

    render() {
        return (
            <div>
                <Button onClick={this.currentNumber} />
            </div>
        );
    }
}

class Button extends React.Component {

    render() {
        return (
            <ul>
            <li><button data-number="1" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>1</button></li>,
            <li><button data-number="2" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>2</button></li>, ...
            <li><button data-number="7" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>7</button></li>
            </ul>
            )
    }
}

ReactDOM.render((<App/>), document.getElementById('testing'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="testing" />