【问题标题】:simple toggle hook in react反应中的简单切换钩子
【发布时间】:2020-09-26 14:56:38
【问题描述】:

我在将切换功能抽象为挂钩时遇到问题。我可以正确切换,但这个钩子代码有问题:

import { useState, useCallback } from "react";

const useToggle = (initialValue = false) => {
  const [value, setValue] = useState(initialValue);

  const toggle = useCallback((defaultValue) => {
    defaultValue !== undefined
      ? setValue(defaultValue) //set true or false
      : setValue((value) => !value); //if param is not supplied, toggle the value
  }, []);

  return [value, toggle];
};

export default useToggle;

https://codesandbox.io/s/goofy-swartz-ztdfb?file=/src/App.js

怎么了?

【问题讨论】:

  • 您好,您能否添加更多信息,例如向我们展示您正在使用此 toggle() 的组件,我的结论之一是您不需要使用 useCallback 挂钩
  • @akibo 您的自定义挂钩很好。请参阅我的回答,以更好地理解为什么您的实现和文章的实现存在差异。
  • @akibo 看看这个链接,看看这是否是你要找的? codesandbox.io/s/relaxed-wilbur-wbu8k?file=/src/App.js

标签: javascript reactjs


【解决方案1】:

在编写此代码时:

<button onClick={toggle}>toggle</button>

您实际上是将事件对象传递给toggle 函数。

onClick={(event) => toggle(event)}
// Same
onClick={toggle}

在您的自定义钩子中,您有条件defaultValue !== undefined,这将产生一个真实值。

因此你应该这样做:

<button onClick={() => toggle()}>toggle</button>

为了您的注意,您可以使用 useReducer 而不是自定义钩子:

const [value,toggle] = useReducer(p=>!p, false);

useToggle 的示例

const useToggle = (initialValue = false) => {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue((value) => !value), []);
  return [value, toggle];
};

【讨论】:

  • 为什么需要使用箭头函数?我从这里joshwcomeau.com/snippets/react-hooks/use-toggle复制源代码,文章有错误吗?
  • 因为再次onClick传递事件对象:onClick={(e) =&gt; toggle(e)}和写onClick={toggle}一样,onClick回调传递e对象。
  • 为什么使用 useReducer 而不是 useState?
  • 文章中没有错误,正如我在答案中解释的那样,defaultValue !== undefined 有错误
  • 你可以使用任何你喜欢的东西,你为什么要使用useState 并从中制作一个自定义钩子,除非你似乎试图保护一个非布尔值:\
【解决方案2】:

你的代码和文章的区别是文章有这个代码:

React.useCallback(()

通知()。它不带任何参数。因此,即使 onClick 传递了事件,它也会在文章代码中被忽略。

但是在你的代码中你是这样使用的:

useCallback((defaultValue)

这里defaultValue 成为事件对象,这就是为什么当您单击切换按钮时会在输出中看到status: [object Object] 的原因,因为事件对象在此调用中被转换为字符串:

status: {open.toString()}

希望这可以澄清!

【讨论】:

    【解决方案3】:

    也许我不明白你想要实现什么,但这样的事情会在真/假之间切换,而且更简单?

     const [toggle, setToggle] = useState(false);
    
      const toggleButtonHandler = () => {
        setToggle(!toggle);
      };
    
      return (
        <div className="App">
          <p>Status: {toggle.toString()}</p>
          <button onClick={setToggle(false)}>false</button>
          <button onClick={toggleButtonHandler}>toggle</button>
        </div>
      );
    

    【讨论】:

      猜你喜欢
      • 2020-11-20
      • 1970-01-01
      • 2021-04-22
      • 2022-01-23
      • 2022-01-15
      • 2023-04-09
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多