#reactjs
#reactjs
Вопрос:
счетчик — это компонент, в котором я поместил кнопку уменьшения в его Я хочу, чтобы, если значение равно нулю, оно перестанет переходить к отрицательным значениям, которые я установил this.setState({counters : counters === 0 ? counters : 0 })
но он не работает, выдавая ошибку
вот мой код
class Counters extends Component {
state={
counters:[
{id:1, value:0},
{id:2, value:0},
{id:3, value:0},
{id:4, value:0}
],
}
handleIncrement=counter=>{
const counters =[...this.state.counters];
const index = counters.indexOf(counter);
counters[index]={...counter}
counters[index].value ;
this.setState({counters})
}
handleDecrement=counter=>{
const counters =[...this.state.counters];
const index = counters.indexOf(counter);
counters[index]={...counter}
counters[index].value--;
this.setState({counters : counters === 0 ? counters : 0 })
}
handleDelete=(counterid)=>{
const counters = this.state.counters.filter(m=>m.id !== counterid)
this.setState({counters})
}
handleReset=()=>{
const counters = this.state.counters.map(m=>{
m.value = 0;
return m
})
this.setState({counters})
}
render() {
return (
<div>
<h1>{this.state.counters.reduce((a,b)=>({value:a.value b.value})).value}</h1>
<button onClick={this.handleReset} className="btn btn-secondary btn-sm">RESET</button>
{this.state.counters.map(m=>
<Counter key={m.id}
id={m.id} getDelete={this.handleDelete}
onIncrement={this.handleIncrement}
onDecrement={this.handleDecrement}
counter={m}
>
</Counter>) }
</div>
);
}
}
Комментарии:
1.
counters
это массив, с чем вы его сравниваете0
? Это всегда будет false, которое вызываетthis.setState({ counters: 0 })
и0
является числом, у которого нетreduce()
метода.2. я хочу остановиться, чтобы перейти к отрицательному уменьшению
3. Вы имели в виду это.setState({счетчики: counters. длина === 0 ? [] : счетчики })
4. @MBB нет, я не думаю, что они это сделали … это тоже не имеет никакого смысла
5. я имею в виду, когда я нажимаю на кнопку уменьшения после нуля, она становится отрицательной -1 -2 -3, я хочу остановиться на нуле
Ответ №1:
Изменить
counters[index].value--;
this.setState({counters : counters === 0 ? counters : 0 });
Для
counters[index].value = Math.max(counters[index].value - 1, 0);
this.setState({ counters });
Ответ №2:
ваша проблема в том, что setState()
не синхронно.
решение заключается в использовании синтаксиса обратного вызова вместо синтаксиса объекта
handleDecrement = counter => {
this.setState(oldstate => ({
counters: oldstate.counters.map(item => {
if (item.id != counter.id) return item;
return {
id: item.id,
value: (item.value > 0) ? (item.value -1) : 0
};
})
}))
}
https://en.reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
Комментарии:
1. почему мы передаем параметр oldstate, вы можете это объяснить
2. this.setState( {счетчики:( oldState.counters > 0) ? (oldState.counters — 1): 0 } ) почему бы не использовать это так
3. setState является асинхронным. таким образом, между временем чтения значения переменной состояния, здесь
counters
и временем обновления значения, эта переменная может изменять значение. итак, если у вас естьcounters = 3
и вы уменьшаете значение в три раза очень быстро, тогда setState будет установленcounters = 2
три раза, и ваше конечное значение будет2
не0
. При использовании синтаксиса функции setState будет использоваться последнее значение, поэтому установите значениеcounters=2
thencounters=1
thencounters=0
4. oldstate не является функцией, почему вы передаете в качестве параметра
5.
oldState => ()
это синтаксис функции со стрелкой, вы можете написать егоfunction (oldState) {}
, если хотите, но в любом случае это функция