ユーザーがxhrを使用してデータをロードするコンポーネントを作成し、値<を選択して>要素を選択します。コンポーネントの状態がselectおよびonChangeハンドラで更新されない
class SomeComponent extends Component {
state = {
data: [],
currentCategory: 'all'
}
switchCategory = (ev) => {
console.log('Selected category is ' + ev.target.value);
this.setState({
currentCategory: ev.target.value
});
this.loadData();
}
loadData = async() => {
let { currentCategory } = this.state;
// Always print previous value!!!
console.log(currentCategory);
// Get data via XHR...
}
render() {
return (
<div>
<select value={currentCategory} onChange={this.switchCategory}>
<option value="all">All</option>
{categories.map(category =>
<option key={category._id} value={category.category}>{category.display}</option>
)}
</select>
<table>
// ... prints data with this.state.data
</table>
</div>
);
}
}
上記のコードは単なる簡単なものです。コードは非常に簡単です、私はちょうどthis.state.currentCategoryとselect要素の値を同期させ、クラスのswitchCategoryメソッドで切り替えることを検出します。
しかし、主な問題は、コンポーネントの状態にアクセスすると、常に前の値であり、存在していないということです。選択した変更の値に対してcurrentCategoryを更新していることがわかります。
switchCategory = (ev) => {
console.log('Selected category is ' + ev.target.value);
this.setState({
currentCategory: ev.target.value
});
this.loadData();
}
したがって、このような状況では、this.state.currentCategoryは何か他のもののように、「アップル」の「すべて」を持っていない必要がありますが、まだそれは「すべて」が含まれ、ない「アップル」!
loadData = async() => {
let { currentCategory } = this.state;
// Always print previous value!!! I expected "Apple", but it has "all"
console.log(currentCategory);
// Get data via XHR...
}
だから、最終的にXHRは、以前の値で発生し、それは私に私は期待していない、間違ったデータを提供します。 その後、セレクト(バナナと呼ぶ)の他の値を選ぶと、バナナではなくアップルが生まれます!
私が知っているように、setStateは "sync"ジョブなので、状態を更新するとthis.switchCategoryを呼び出すので、以前の値ではなく現在の値が必要です。
しかし、コンポーネントの状態をコンソールに表示するときは、そうではありません。
私は何が欠けていますか?なぜ私は古いデータをいつも持っているのですか?私が何か間違ったアプローチをしていたら、私は何をすることができますか?
アドバイスはありがたいです。ありがとう!
反応し、選択したカテゴリのプリントが右の選択したカテゴリを印刷していますか?非同期を削除しようとしましたか? – Kinnza
onChangeをバインドしましたか?あなたのクラスの最上部とコンストラクタにコンストラクタを追加してください: 'this.onChange = this.onChange.bind(this)' – Celebrian
あなたを助けてくれてありがとう! – modernator