猿问

传递值的反应钩子问题|| defaultValue 和更新计数器

在下面找到示例代码和屏幕截图。

两个问题:

  1. counter没有正确更新,是否允许写类似的东西setCounter((prev) => { return { counter: prev.counter - value || 1 }});

  2. setCounter(counter + value || 1)什么是正确的工作方式,在缺少实际值的情况下使用 1 ?

在下面找到示例代码和屏幕截图。

const Counter = (props) => {

  const [counter, setCounter] = useState(0);


  const handleCounterChange = (action, value) => {

    switch (action) {

      case "+":

        setCounter(counter + value || 1);

        break;

      case "-":

        setCounter(counter - value || 1);

        break;

      default:

        setCounter(counter + value || 1);

        break;

    }

  };


  return (

    <div className={classes.Counter}>

      <CounterOutput value={counter} />

      <CounterControl

        label="+"

        clicked={() => handleCounterChange("+")}

      />

      <CounterControl

        label="-"

        clicked={() => handleCounterChange("-")}

      />

      <CounterControl

        label="+ 5"

        clicked={() => handleCounterChange("+", 5)}

      />

      <CounterControl

        label="- 5"

        clicked={() => handleCounterChange("-", 5)}

      />

    </div>

  );

};


export default Counter;

忽然笑
浏览 254回答 3
3回答

Qyouu

问题setCounter(counter + value || 1);在于 JS 会先尝试计算,counter + value&nbsp;然后再进行布尔测试。因此,例如,如果您的counter值为1并且减去 的值1,则结果为0,这是错误的,因此1将保存为 的新值counter。这可能不是你想要的。console.log(100&nbsp;+&nbsp;undefined&nbsp;||&nbsp;1);&nbsp;//&nbsp;expect&nbsp;101&nbsp;but&nbsp;result&nbsp;is&nbsp;1&nbsp; console.log(1&nbsp;+&nbsp;-1&nbsp;||&nbsp;1);&nbsp;//&nbsp;expect&nbsp;0&nbsp;but&nbsp;result&nbsp;is&nbsp;1不过,您可以对优先级进行分组,即counter + (value || 1).console.log(100&nbsp;+&nbsp;(undefined&nbsp;||&nbsp;1));&nbsp;//&nbsp;101如果您只是想提供默认值 1 ,value那么您可以在签名中执行此操作。如果value未定义,它将被分配 的值1。并使用功能状态更新。const handleCounterChange = (action, value = 1) => {&nbsp; switch (action) {&nbsp; &nbsp; case "+":&nbsp; &nbsp; &nbsp; setCounter(counter => counter + value);&nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; case "-":&nbsp; &nbsp; &nbsp; setCounter(counter => counter - value);&nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; setCounter(counter => counter + value);&nbsp; &nbsp; &nbsp; break;&nbsp; }};关于这种“reducer”类型模式的一个侧面说明是,如果该操作不是您专门处理的操作,则返回现有状态。const handleCounterChange = (action, value = 1) => {&nbsp; switch (action) {&nbsp; &nbsp; case "+":&nbsp; &nbsp; &nbsp; setCounter(counter => counter + value);&nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; case "-":&nbsp; &nbsp; &nbsp; setCounter(counter => counter - value);&nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; // ignore, i.e. don't update state at all&nbsp; &nbsp; &nbsp; break;&nbsp; }};

慕村9548890

这里提出了几个优秀的重构。我肯定想通读这些建议并进行重构。至于您不可预测的计数器的原因,假设单击参数正在进入您的状态更新函数,则存在操作顺序问题。考虑这种情况。值为undefined从上面代码的编写方式来看,当 value 为 时undefined,我们希望value在 state 中添加一个数字counter。由于操作顺序,这不是正在发生的事情。这个错误隐藏在明显的视线中,因为经常value和counter两者都是1,所以看起来状态没有改变。> let value = undefinedundefined> let counter = 1undefined> counter + value || 100100最后一条语句说“将计数器加起来undefined”,这NaN也是错误的。在这种情况下,结果将始终是“或”语句的另一端100。使用括号更改操作顺序,并创建所需的行为。> counter + (value || 100)101

MM们

本身不是一个答案,但不要使用额外的不必要的功能使您的代码过于复杂。您的逻辑是如此简单,添加额外的功能会使阅读变得更加复杂并添加奇怪的逻辑(默认值是什么?)&nbsp; return (&nbsp; &nbsp; <div className={classes.Counter}>&nbsp; &nbsp; &nbsp; <CounterOutput value={counter} />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="+"&nbsp; &nbsp; &nbsp; &nbsp; clicked={() => setCounter(state => state+1)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="-"&nbsp; &nbsp; &nbsp; &nbsp; clicked={() => setCounter(state => state-1)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="+ 5"&nbsp; &nbsp; &nbsp; &nbsp; clicked={() => setCounter(state => state+5)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="- 5"&nbsp; &nbsp; &nbsp; &nbsp; clicked={() => setCounter(state => state-5)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; </div>&nbsp; );如果你想再干一点,你总是可以做这样的事情:&nbsp; const change = by => () => setCounter(count => count+by)&nbsp; return (&nbsp; &nbsp; <div className={classes.Counter}>&nbsp; &nbsp; &nbsp; <CounterOutput value={counter} />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="+"&nbsp; &nbsp; &nbsp; &nbsp; clicked={change(1)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="-"&nbsp; &nbsp; &nbsp; &nbsp; clicked={change(-1)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="+ 5"&nbsp; &nbsp; &nbsp; &nbsp; clicked={change(5)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; <CounterControl&nbsp; &nbsp; &nbsp; &nbsp; label="- 5"&nbsp; &nbsp; &nbsp; &nbsp; clicked={change(-5)}&nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; </div>&nbsp; );
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答