Incrementing state value by one using React

扶醉桌前 提交于 2019-12-03 03:49:13

问题


In React I am trying to make a button increment a value stored in state. However using the code below function my value is set undefined or NaN when using handleClick.

class QuestionList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 0};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

   handleClick = (prevState) => {
    this.setState({value: prevState.value + 1});
    console.log(this.state.value)
  }

Can you tell me why this is happening? it should be correct according to the docs here: https://facebook.github.io/react/docs/state-and-lifecycle.html


回答1:


Because you are using the handleClick function incorrectly. Here:

handleClick = (prevState) => { .... }

prevState will be an event object passed to handleClick function, you need to use prevState with setState, like this:

handleClick = () => {
    this.setState(prevState => {
       return {count: prevState.count + 1}
    })
}

Another issue is, setState is async so console.log(this.state.value) will not print the updated state value, you need to use callback function with setState.

Check more details about async behaviour of setState and how to check updated value.

Check the working solution:

class App extends React.Component {
 
   constructor(props){
       super(props);
       this.state={ count: 1}
   }
 
  onclick(type){
      this.setState(prevState => {
         return {count: type == 'add' ? prevState.count + 1: prevState.count - 1}
      });
  }

   render() {
    return (
      <div>
        Count: {this.state.count}
        <br/>
        <div style={{marginTop: '100px'}}/>
        <input type='button' onClick={this.onclick.bind(this, 'add')} value='Inc'/>
        <input type='button' onClick={this.onclick.bind(this, 'sub')} value='Dec'/>
       </div>
     )
   }
}

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

<div id='container'></div>



回答2:


set state is async so you wont see the value update when the console.log happens. You should have the state value printed out on the UI so you can see whats happening. To fix the console log try this.

class QuestionList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 0};
  }

   handleClick = (prevState) => {
    this.setState({value: prevState.value + 1}, () => {
        console.log(this.state.value)
    });
  }

NOTE: when you define an inline lambda (arrow function) for a react class this is bound correctly so you dont need to bind it in the constructor.

also you can change the way you pass the previous number if its just a state increment like this

handleClick = () => {
    this.setState({value: this.state.value + 1}, () => {
        console.log(this.state.value)
    });
}



回答3:


class SkuVariantList extends React.Component {
    constructor(props) {
      super(props)
      this.state = {
        clicks: 0
      };
      this.clickHandler = this.clickHandler.bind(this)
    }

    componentDidMount() {
      this.refs.myComponentDiv.addEventListener('click', this.clickHandler);
    }

    componentWillUnmount() {
      //this.refs.myComponentDiv.removeEventListener('click', this.clickHandler);
    }

    clickHandler() {
      var clk = this.state.clicks
      this.setState({
        clicks: clk + 1
      });
    }

    render() {
      let children = this.props.children;

      return (
        <div className="my-component" ref="myComponentDiv">
          <h2>My Component ({this.state.clicks} clicks})</h2>
          <h3>{this.props.headerText}</h3>
          {children}
        </div>
      );
    }
  }



回答4:


Hello there, try these codes to increment your value

class Counter extends React.Component{
 constructor(props){
   super(props);
     this.addOne = this.addOne.bind(this);
       this.state = {
         count : 0 
       }
    }

addOne() {                              // addOne as HandleClick
  this.setState((preState) => {
    return {
      count : preState.count + 1
      };
   });
 }

render() {
   return (
      <div>
        <h1>Count : {this.state.count}</h1>
        <button onClick={this.addOne}>+1</button>
      </div>
     );
   }
 }

ReactDOM.render(<Counter />, document.getElementById('YOUR-ID'));



回答5:


Try this out

class QuestionList extends React.component {

    constructor(props){
        super(props)
        this.state = {
            value : 0
        }
    }

    handleClick(){
        this.setState({
            value : this.state.value + 1
        })
    }

   render(){
        return( <button type="button" onClick={this.handleClick.bind(this)}> {this.state.value} </button> )
   }
}

Note that when you set a state, it triggers the render function, which will reflect the current state. Try it out in the browser!




回答6:


import React from 'react'

class App extends React.Component{
  constructor(){
    super()
    this.state = {
      count: 0
    }
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick(){
    this.setState(prevState => {
      return {
        count: prevState.count + 1
      }
    })
  }
  render(){
    return(
      <div style = {{display: 'flex', fontSize: 30, flexDirection: 'column', alignItems:'center'}}>
        <h1>{this.state.count}</h1>
        <button onClick = {this.handleClick}>Change</button>
      </div>
    )
  }
}
export default App



回答7:


This is the shortest code for that. First, initialize the state, then perform a method to increment.

state = {
    counter: 0
  }
increaseHandler = () => {
    let counter = this.state.counter
    counter += 1
    this.setState({counter: counter})
  }


来源:https://stackoverflow.com/questions/42364838/incrementing-state-value-by-one-using-react

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!