使用React中的钩子来改变布尔值并获取回调

5
我正在尝试在React中使用钩子。这个钩子应该给我一个布尔值和一个回调函数。当回调被调用时,布尔值应该改变。当我试图检索值和回调函数时,出现了错误。
“isEnabled”属性在类型“(boolean | (() => void))[]”上不存在。在行“const {isEnabled, toggleCallback} = useToggle();”上出错了。
我做错了什么?
function toggleCallback(toggleCallback: () => void) {
    toggleCallback();
}

export default function FakePage(props: any) {
    const {isEnabled, toggleCallback} = useToggle();
    return (
        <div>
            <ComponentOne isEnabled={isEnabled}/>
            <button onClick={() => testToggle(toggleCallback)}>Test</button>
        </div>
    );
}

// hook
export default function useToggle() {
    let isEnabled: boolean = true;
    const toggleCallback= useCallback(() => {
        isEnabled = !isEnabled;
    }, [isEnabled]);
    return [isEnabled, toggleCallback];
}

你从钩子中返回了一个数组,但是你将其解构为一个对象。要么从回调函数中删除方括号并添加花括号,要么将组件中的花括号改为方括号。 - Dilshan
值得注意的是,在您的钩子中应使用useState()来处理isEnabled。此外,您可能不需要使用useCallback,因为当isEnabled为true和false时,它将起到相同的作用。 - Deykun
2个回答

4
关于错误和类型,目前您正在返回一个包含布尔类型和函数类型 ( ) => void 的列表,而您想要返回一个元组。
// Return from custom hook
return [isEnabled, toggleCallback];

// use it like so, and not as object { isEnabled,setIsEnbaled }
const [isEnabled,setIsEnbaled] = useToggle();

使用下列方式修复返回类型:

return [isEnabled, toggleCallback] as const;

或者指定返回类型:

type HookProps = (initialState: boolean) => [boolean, () => void];
const useToggle: HookProps = (initialState) => {...}

关于钩子实现,JS中应该如下所示,由于变量没有与状态连接,因此在您的示例中使用toggleCallback不会触发渲染。
function useToggle(initialValue = true) {
  const [isEnabled, toggle] = useReducer((p) => !p, true);
  return [isEnabled, toggle];
}

3
如何创建自定义钩子:
export default function FakePage(props: any) {
    const {isEnabled, toggleCallback} = useToggle();
    return (
        <div>
            <ComponentOne isEnabled={isEnabled}/>
            <button onClick={toggleCallback}>Test</button>
        </div>
    );
}

// hook
export default function useToggle() {
    const [isEnabled,setIsEnabled] = useState(true)
    const toggleCallback= () => {
       setIsEnabled(current=>!current);
    };// no need to useCallback
    return {isEnabled, toggleCallback};
}

// and if you want to pass default value 

   export default function useToggle(default) {
        const [isEnabled,setIsEnabled] = useState(default)
        const toggleCallback= () => {
           setIsEnabled(current=>!current);
        };// no need to useCallback
        return {isEnabled, toggleCallback};
    }
// usage 
const {isEnabled, toggleCallback} = useToggle(false);

你应该添加一些解释,仅仅说“不需要使用useCallback”并不能很好地进行教学/解释。 - Dennis Vash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接