web-dev-qa-db-ja.com

Reactを使用して状態値を1つずつ増加させる

In React状態に保存されている値をボタンで増加させようとしています。ただし、以下のコードを使用すると、handleClickの使用時に値がundefinedまたはNaNに設定されます。

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)
  }

これがなぜ起こっているのか教えてもらえますか?ここのドキュメントに従って正しいはずです: https://facebook.github.io/react/docs/state-and-lifecycle.html

19
dwigt

HandleClick関数を誤って使用しているため。ここに:

_handleClick = (prevState) => { .... }
_

prevStateは、handleClick関数に渡されるイベントオブジェクトになります。次のように、setStateでprevStateを使用する必要があります。

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

もう1つの問題は、setStateが非同期であるため、console.log(this.state.value)が更新された状態値を出力しないため、setStateでコールバック関数を使用する必要があることです。

setStateの非同期動作 および更新された値を確認する方法の詳細を確認してください。

動作中のソリューションを確認します。

_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>_
21
Mayank Shukla

設定状態は非同期なので、console.logが発生しても値の更新は表示されません。何が起こっているのかを確認できるように、UIに状態値を印刷する必要があります。コンソールログを修正するには、これを試してください。

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)
    });
  }

注:反応クラスのインラインラムダ(矢印関数)を定義すると、thisは正しくバインドされるため、コンストラクタでバインドする必要はありません。

また、そのような状態がこのように増加する場合は、前の番号を渡す方法を変更できます

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

こんにちは、これらのコードを試して値を増やしてください

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'));
2
user8290176
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>
      );
    }
  }
2
D V Yogesh

これを試してください

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> )
   }
}

状態を設定すると、レンダリング関数がトリガーされ、現在の状態が反映されることに注意してください。ブラウザで試してみてください!

1
ChannelJuanNews

これはそのための最短のコードです。最初に状態を初期化してから、インクリメントするメソッドを実行します。

state = {
    counter: 0
  }
increaseHandler = () => {
    let counter = this.state.counter
    counter += 1
    this.setState({counter: counter})
  }
0
Seyi Oluwadare
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
0
Colloh