我有一个基本的反应上下文,类似于以下内容:
function IdProvider({ children }: any) {
const [id, setId] = useState("DEFAULT_ID")
return (
<IdContext.Provider value={{ id, setId }}>
{children}
</IdContext.Provider>
)
}
我正在使用此提供程序包装我的所有路由,并且有一个组件,如下所示,我想用它来更新 Id:
function UpdateForm() {
const { id, setId } = useId() // wrapper for the IdContext
const moveToDisplay = (newId: string) => {
setId(newId)
window.location.href = "/display/" + id
}
return (
<>
<span onClick={() => moveToDisplay("NEW_ID")}>
Update and redirect
</span>
</>
)
}
重定向时,使用此组件:
function DisplayId(): JSX.Element {
const { id } = useId()
useEffect(() => {
document.title = id
}, [id])
return (
<>
{id}
</>
)
}
问题是,最初的 setId(newId)
不会更新状态,所以当 window.location.href = "/display/" + id
被调用时,它会重定向到 /display/DEFAULT_ID
,而 DisplayId
组件仍然使用呈现时的 DEFAULT_ID
值。根据我的理解,useState
是异步的,所以我不完全确定我应该如何解决这个问题。我尝试在调用 setId
后添加 5 秒超时,但 id
的值仍然是默认值。
编辑 - 已解决
弄清楚了这个问题,它是相当不相关的。我使用了一个常量(例如 DEFAULT_ID
)来初始化各个地方的状态,却没有意识到 React 在更新/重新渲染时会检查引用相等性。
答案 0 :(得分:0)
useContext 提供了通过组件的反应链传递属性的能力。因此,将您的提供商更改为此并确保它正在导出
<IdContext.Provider value={id}>
然后在您的孩子中,您可以通过导入上下文来更新它:
import IdContext from './IdProvider'
和使用上下文:
const [context, setContext] = useContext(IdContext)
然后用新值设置它:
const moveToDisplay = (newId: string) => {
setContext(newId)
window.location.href = "/display/" + newId
}
之后,您通过 DisplayId 以相同的方式导入它并使用该值