У меня есть этот фрагмент кода:
handleMaxLevel = event => {
this.setState({
maxLevel: event.target.value
}, (minLevel, maxLevel) => {
let filter = this.state.filteredPlayers.filter(players => {
return players.level > minLevel && players.level < maxLevel
})
this.setState({
levelFilteredPlayers: filter
})
})
}
Я вызываю эту функцию в этом фрагменте кода:
<TextField
id = "standard-number"
label = "Highest level"
type = "number"
onChange = {() => this.handleMaxLevel(this.state.minLevel, this.state.maxLevel)}
InputLabelProps = {{
shrink: true,
}}
/>
Что я получаю: TypeError: Невозможно прочитать значение свойства undefined
Пишет, что проблема в этой строке: maxLevel: event.target.value.
Я не понимаю, разве обратный вызов не должен ждать завершения первого setstate, чтобы он выполнялся?
Почему он не восстанавливает значение, установленное в состояние maxLevel?
Ваш синтаксис неверен. Когда вы вызываете handleMaxLevel
, вы должны передавать ему объект события. А обратному вызову setState
не нужны никакие аргументы, он уже имеет доступ к обновленному состоянию. Итак, ваш обработчик onChange
должен быть таким:
onChange = {handleMaxLevel} // If we pass function directly, it will be given the event argument by default
а затем в обратном вызове setState
обратитесь непосредственно к значениям состояния, так как в обратном вызове они будут обновлены:
handleMaxLevel = event => {
this.setState({
...this.state,
maxLevel: event.target.value
}, () => {
let filter = this.state.filteredPlayers.filter(players => {
return players.level > this.state.minLevel && players.level < this.state.maxLevel
})
this.setState({
...this.state,
levelFilteredPlayers: filter
})
})
}
Обновлено: я считаю, что вам также нужно распространять старое состояние, чтобы предотвратить потерю значений. Кроме того, вероятно, лучше просто сделать все это в одном вызове setState
, а не использовать обратный вызов
Что здесь не так, так это то, что ваша функция ожидает один аргумент
const handleMaxLevel = event => {
// ...
}
но ваш вызов отправляет два аргумента
onChange = {() => this.handleMaxLevel(this.state.minLevel, this.state.maxLevel)}
Если вы хотите изменить свою функцию, чтобы принимать переменные событий и переменных состояния:
// Change invocation like so:
onChange = {event => this.handleMaxLevel(event, this.state.minLevel, this.state.maxLevel)}
// Change function definition like so:
const handleMaxLevel = (event, minLevel, maxLevel) => {
// ...
}
но, поскольку вы просто используете атрибуты состояния внутри функции, вам даже не нужно передавать их явно:
onChange = {e => this.handleMaxLevel(e)}
это позволит вам сделать вашу функцию такой:
const handleMaxLevel = event => {
// access state attributes like this:
const {minLevel, maxLevel} = this.state;
// and now you also have access to the event value
this.setState({ maxValue: e.target.value });
}