我在将我的切换功能抽象到一个钩子时遇到问题。我可以进行正确的切换,但是此挂钩代码有问题:
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
怎么了?
答案 0 :(得分:0)
编写此代码时:
<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];
};
答案 1 :(得分:0)
您的代码与本文的区别在于该文章具有以下代码:
React.useCallback(()
通知()
。它不带任何参数。因此,即使onClick通过事件,文章代码中也会忽略它。
但是在您的代码中,您是这样使用的:
useCallback((defaultValue)
这里defaultValue
成为事件对象,这就是为什么在单击切换按钮时在输出中看到status: [object Object]
的原因,因为此调用将事件对象转换为字符串:
status: {open.toString()}
希望这可以澄清!
答案 2 :(得分:0)
也许我不明白您要达到的目标,但是这样的事情会在true / false和更简单之间切换?
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>
);