[英]useState setter function is not updating state in react
我在两个组件CustomCodeEditor
和EditorFooter
中使用useIsDirty
挂钩来跟踪编辑器中的代码是否已被修改。 钩子返回一个isDirty
state 和一个setIsDirty
function 来更新它。 当我在CustomCodeEditor
组件中调用setIsDirty(true)
时,state 被更新,但是当我在EditorFooter
组件中调用setIsDirty(false)
时,它似乎没有更新isDirty
state。我相信这是因为 EditorFooter 组件确实无法访问更新的 state。任何人,请帮我解决这个问题。
使用是脏的:
import { useEffect, useState } from "react"
const useIsDirty = () => {
const [isDirty, setIsDirty] = useState(false)
useEffect(() => {
const handleBeforeUnload = (event) => {
if (isDirty) {
event.preventDefault()
event.returnValue = ""
alert("You have unsaved changes, are you sure you want to leave?")
}
}
console.log("Diryt:", isDirty)
window.addEventListener("beforeunload", handleBeforeUnload)
return () => {
window.removeEventListener("beforeunload", handleBeforeUnload)
}
}, [isDirty])
return { isDirty, setIsDirty }
}
export default useIsDirty
自定义代码编辑器
import Editor from "@monaco-editor/react"
import useIsDirty from "../../hooks/useIsDirty"
const CustomCodeEditor = () => {
const { isDirty, setIsDirty } = useIsDirty()
console.log("isDirty:", isDirty)
return (
<div className="bg-[#1e1e1e] h-full">
<Editor
onChange={(value) => {
updateCode(value || "")
setIsDirty(true) // updating state
}}
/>
</div>
)
}
export default CustomCodeEditor
编辑器页脚
import Button from "../reusable/Button"
const EditorFooter = () => {
const { setIsDirty } = useIsDirty()
const handleSave = async () => {
setIsDirty(false)
}
return (
<div>
<Button
onClick={handleSave}
>
Save
</Button>
<Button
onClick={handleSave}
>
Submit
</Button>
</div>
)
}
export default EditorFooter
钩子不是 singleton 个实例。当你在某处使用useIsDirty
时。它总是创建新实例,与其他实例具有不相关的状态。 如果你想分享这个 state 你需要使用Context
const IsDirtyContext = createContext(undefined);
const IsDirtyProvider = ({ children }): ReactElement => {
const [isDirty, setIsDirty] = useState(false)
return <IsDirtyContext.Provider value={{isDirty, setIsDirty}}>{children}</IsDirtyContext.Provider>;
};
然后你应该用IsDirtyProvider
把你的组件树包装在你想访问它的地方
之后,您甚至可以创建只返回该上下文的自定义挂钩:
const useIsDirty = () => {
return useContext(IsDirtyContext)
}
查看您的问题,您似乎正在尝试在两个组件中使用相同的 state。 然而,state 并不是那样工作的。 每当您从不同的组件调用 useIsDirty 时,都会创建一个新实例。
如果要跨两个组件使用 state 值。 您可以使用以下方法之一来执行此操作。
1 - 使用父子层次结构。
脚步
现在您应该能够在两个组件之间共享您的 state。
2 - 使用上下文 api。
如果你不了解 api 是什么上下文,下面简单解释一下。
上下文 api 可帮助您在组件之间共享数据,而无需将它们作为 prop 传递给每个组件。
您可以使用上下文 api 中的 createContext 和 useContext 挂钩。
createContext用于创建新的上下文提供程序。
useContext钩子用于全局管理 state。 您可以使用此 function 从上下文中获取值。每当 state 更新时,该值将在全球范围内反映出来。
注意 - 任何需要使用 useContext 中的值的组件都应该包装在 useContext 提供程序组件中。
创建上下文提供程序的步骤。 要创建上下文,您只需要使用 react hook createContext
使用以下代码创建上下文
const isDirtyContext = createContext();
将您的组件包装在上下文提供程序中
从 './path/filename' 导入 {IsDirtyContext}
<IsDirtyContext.Provider value={[isDirty, setIsDirty]}>{children}</IsDirtyContext.Provider>
如果您的上下文在一个单独的文件中,那么您可以使用 import 语句将其导入到任何子组件中。
从 './path/filename' 导入 {IsDirtyContext}
使用上下文
const [isDirty] = useContext(IsDirtyContext);
现在 isDirty state 值在所有组件中全局可用。
希望这些信息对您有所帮助。 如果这有助于您理解和解决问题,请点赞。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.