尝试设置状态时出现无效的钩子调用错误
我遇到一种情况,我被迫从两个不同的地方调用触发器方法来显示模态框,一个地方使用热键组合,另一个地方通过单击工具栏按钮。为了做到这一点,我有以下代码,其中我调用
triggerCustomLinkModal
来设置状态,但随后我遇到了
无效钩子调用错误
。
import { useState, useCallback, useEffect } from "react"
import { Dialog } from "@blueprintjs/core"
const useLocalState = () => {
const [isShown, setIsShown] = useState(false)
const setState = useCallback((state) => {
setIsShown(state)
})
const getState = useCallback(() => {
return isShown
})
return {
setState,
getState
}
}
export const CustomLinkModalUI = () => {
const { getState } = useLocalState()
return (
<>
<Dialog isOpen={getState()} />
</>
)
}
export const triggerCustomLinkModal = () => {
const { setState } = useLocalState()
setState()
}
从评论中的 Chris 的回答扩展(您不能在
React 组件
之外使用钩子。-> 因此您无法在
triggerCustomLinkModal
内部调用
useLocalState()
,因为
triggerCustomLinkModal
不是 React 组件):
您实际上并不需要 useCallback 钩子,甚至不需要函数本身。根据 react docs :
Note
React guarantees that setState function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list.
这也意味着使用
useCallback
钩子来设置状态实际上没有任何意义(因为 useCallback 的作用只是返回
记忆化回调
)
您基本上需要的是在最近的父组件中设置状态,并传递
setIsShown
作为 prop 以及
isShown
函数。
您当前的实现,即使没有错误,它也不会引用相同的状态,因为在每个
useLocalState()
上您都在初始化一个全新的状态(因此您不是在指向相同的状态
CustomLinkModalUI
和
triggerCustomLinkModal
)