3 回答
TA贡献1786条经验 获得超11个赞
问题setCounter(counter + value || 1);在于 JS 会先尝试计算,counter + value 然后再进行布尔测试。因此,例如,如果您的counter值为1并且减去 的值1,则结果为0,这是错误的,因此1将保存为 的新值counter。这可能不是你想要的。
console.log(100 + undefined || 1); // expect 101 but result is 1 console.log(1 + -1 || 1); // expect 0 but result is 1
不过,您可以对优先级进行分组,即counter + (value || 1).
console.log(100 + (undefined || 1)); // 101
如果您只是想提供默认值 1 ,value那么您可以在签名中执行此操作。如果value未定义,它将被分配 的值1。并使用功能状态更新。
const handleCounterChange = (action, value = 1) => {
switch (action) {
case "+":
setCounter(counter => counter + value);
break;
case "-":
setCounter(counter => counter - value);
break;
default:
setCounter(counter => counter + value);
break;
}
};
关于这种“reducer”类型模式的一个侧面说明是,如果该操作不是您专门处理的操作,则返回现有状态。
const handleCounterChange = (action, value = 1) => {
switch (action) {
case "+":
setCounter(counter => counter + value);
break;
case "-":
setCounter(counter => counter - value);
break;
default:
// ignore, i.e. don't update state at all
break;
}
};
TA贡献1884条经验 获得超4个赞
这里提出了几个优秀的重构。我肯定想通读这些建议并进行重构。
至于您不可预测的计数器的原因,假设单击参数正在进入您的状态更新函数,则存在操作顺序问题。考虑这种情况。
值为undefined
从上面代码的编写方式来看,当 value 为 时undefined,我们希望value在 state 中添加一个数字counter。由于操作顺序,这不是正在发生的事情。这个错误隐藏在明显的视线中,因为经常value和counter两者都是1,所以看起来状态没有改变。
> let value = undefined
undefined
> let counter = 1
undefined
> counter + value || 100
100
最后一条语句说“将计数器加起来undefined”,这NaN也是错误的。在这种情况下,结果将始终是“或”语句的另一端100。
使用括号更改操作顺序,并创建所需的行为。
> counter + (value || 100)
101
TA贡献1886条经验 获得超2个赞
本身不是一个答案,但不要使用额外的不必要的功能使您的代码过于复杂。您的逻辑是如此简单,添加额外的功能会使阅读变得更加复杂并添加奇怪的逻辑(默认值是什么?)
return (
<div className={classes.Counter}>
<CounterOutput value={counter} />
<CounterControl
label="+"
clicked={() => setCounter(state => state+1)}
/>
<CounterControl
label="-"
clicked={() => setCounter(state => state-1)}
/>
<CounterControl
label="+ 5"
clicked={() => setCounter(state => state+5)}
/>
<CounterControl
label="- 5"
clicked={() => setCounter(state => state-5)}
/>
</div>
);
如果你想再干一点,你总是可以做这样的事情:
const change = by => () => setCounter(count => count+by)
return (
<div className={classes.Counter}>
<CounterOutput value={counter} />
<CounterControl
label="+"
clicked={change(1)}
/>
<CounterControl
label="-"
clicked={change(-1)}
/>
<CounterControl
label="+ 5"
clicked={change(5)}
/>
<CounterControl
label="- 5"
clicked={change(-5)}
/>
</div>
);
添加回答
举报
