わかりました、簡単に修正できるはずですので、これをすばやく試してみます...
似たような質問をたくさん読みましたが、その答えは非常に明白です。そもそも見上げる必要はありません!しかし...私は、修正方法やその理由を推測できないエラーを抱えています。
次のように:
_class NightlifeTypes extends Component {
constructor(props) {
super(props);
this.state = {
barClubLounge: false,
seeTheTown: true,
eventsEntertainment: true,
familyFriendlyOnly: false
}
this.handleOnChange = this.handleOnChange.bind(this);
}
handleOnChange = (event) => {
if(event.target.className == "barClubLounge") {
this.setState({barClubLounge: event.target.checked});
console.log(event.target.checked)
console.log(this.state.barClubLounge)
}
}
render() {
return (
<input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
)
}
_
より多くのコードがこれを囲んでいますが、これが私の問題のあるところです。動作するはずですよね?
私もこれを試しました:
_handleOnChange = (event) => {
if(event.target.className == "barClubLounge") {
this.setState({barClubLounge: !this.state.barClubLounge});
console.log(event.target.checked)
console.log(this.state.barClubLounge)
}
_
そのため、これら2つのconsole.log()
があり、両方とも同じでなければなりません。文字通り、状態をその上の行の_event.target.checked
_と同じに設定しています!
しかし、それは常に本来の反対を返します。
_!this.state.barClubLounge
_を使用する場合も同様です。 falseで始まる場合、チェックボックスがチェックされているかどうかは状態に基づいていても、最初のクリックではfalseのままです!!
それは狂ったパラドックスであり、私は何が起こっているのか分かりません、助けてください!
理由はsetStateは非同期です。state
メソッドを使用して値を確認する場合は、setState
の直後に更新されたcallback
値を期待できません。 setState
がタスクを完了した後に実行されるメソッドをコールバックとして渡します。
SetStateが非同期なのはなぜですか?
これは、setState
がstate
を変更し、再レンダリングを引き起こすためです。これは高価な操作になる可能性があり、synchronous
にするとブラウザが応答しなくなる場合があります。したがって、setState
呼び出しは、asynchronous
であり、UIエクスペリエンスとパフォーマンスを向上させるためにバッチ処理されます。
From Docから:
setState()はすぐにthis.stateを変更しませんが、保留状態遷移を作成します。このメソッドを呼び出した後にthis.stateにアクセスすると、既存の値が返される可能性があります。 setStateの呼び出しの同期操作の保証はなく、パフォーマンス向上のために呼び出しをバッチ処理できます。
setStateでのコールバックメソッドの使用:
state
の直後の更新されたsetState
値を確認するには、次のようなコールバックメソッドを使用します。
setState({ key: value }, () => {
console.log('updated state value', this.state.key)
})
これをチェックして:
class NightlifeTypes extends React.Component {
constructor(props) {
super(props);
this.state = {
barClubLounge: false,
seeTheTown: true,
eventsEntertainment: true,
familyFriendlyOnly: false
}
}
handleOnChange = (event) => { // Arrow function binds `this`
let value = event.target.checked;
if(event.target.className == "barClubLounge") {
this.setState({ barClubLounge: value}, () => { //here
console.log(value);
console.log(this.state.barClubLounge);
//both will print same value
});
}
}
render() {
return (
<input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
)
}
}
ReactDOM.render(<NightlifeTypes/>, document.getElementById('app'))
<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='app'/>
SetStateは非同期関数であるため。つまり、setState状態変数を呼び出した後、すぐには変更されません。したがって、状態を変更した直後に他のアクションを実行する場合は、setState更新関数内でsetstateのコールバックメソッドを使用する必要があります。
handleOnChange = (event) => {
let inputState = event.target.checked;
if(event.target.className == "barClubLounge") {
this.setState({ barClubLounge: inputState}, () => { //here
console.log(this.state.barClubLounge);
//here you can call other functions which use this state
variable //
});
}
}
これは、パフォーマンスを考慮した設計によるものです。 setState in Reactは関数です保証は、高コストのCPUプロセスであるコンポーネントを再レンダリングします。そのため、設計者は複数のレンダリングアクションをそのため、setStateは非同期です。