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>
);
添加回答
舉報