处理 window 事件时的本地状态值错误 (React)
Wrong local state value when a handling a window event (React)
我有一个状态值 ccFormDetails
,其中一个空对象作为默认值。
const [ccFormDetails, setCCFormDetails] = useState({})
首先 useEffect
,我调用了一个函数,用相关数据填充 ccFormDetails
。
const getCCFormData = async () => {
const ccFormResult = await ContractService.getContractsCCFormData()
const { ccFormData } = ccFormResult
setCCFormDetails(ccFormData)
}
在第二个 useEffect
中,我创建了一个名为 message
的事件并为其分配了一个 handleCgEvent
处理程序。
useEffect(() => {
window.addEventListener('message', handleCgEvent)
return () => window.removeEventListener('message', handleCgEvent)
}, [])
我正在渲染一个带有提交按钮的 iframe
,单击该按钮会发出 message
事件。
然后,当我单击 iframe
中的 sumbit 按钮时,handleCgEvent
处理程序将触发并应提取 ccFormDetails
的正确(更新的、已检测的)值。 (我可以在 React 组件树中看到正确填充)
const handleCgEvent = e => {
if (e.data === 'reload_cg') {
console.log('fail')
}
if (e.data['event_id'] === 'cg-success') {
console.log('success')
console.log('ccFormDetails1 ', ccFormDetails)
}
}
但我得到的是 {}
表示原始默认状态。
根据我对 React 的了解,这不应该发生。
我是否缺少 something/Does 事件处理混乱状态?
这里的问题是您正在使用安装组件时创建的 handleCgEvent
,并且 ccFormDetails
使用其默认值封装在其中。为了获得最新状态,您将不得不使用 useRef。类似于:
const [ccFormDetails, setCCFormDetails] = useState({})
const formRef = useRef();
formRef.current = ccFormDetails;
const handleCgEvent = e => {
if (e.data === 'reload_cg') {
console.log('fail')
}
if (e.data['event_id'] === 'cg-success') {
console.log('success')
console.log('ccFormDetails1 ', formRef.current)
}
}
useEffect(() => {
window.addEventListener('message', handleCgEvent)
return () => window.removeEventListener('message', handleCgEvent)
}, []);
如果您可以添加和删除事件侦听器,那么我将添加 [ccFormDetails]
作为依赖项,假设在其属性更改时重新创建整个对象。
要进一步阅读闭包中的陈旧值,这是一篇很棒的博客文章:https://dmitripavlutin.com/react-hooks-stale-closures/
我有一个状态值 ccFormDetails
,其中一个空对象作为默认值。
const [ccFormDetails, setCCFormDetails] = useState({})
首先 useEffect
,我调用了一个函数,用相关数据填充 ccFormDetails
。
const getCCFormData = async () => {
const ccFormResult = await ContractService.getContractsCCFormData()
const { ccFormData } = ccFormResult
setCCFormDetails(ccFormData)
}
在第二个 useEffect
中,我创建了一个名为 message
的事件并为其分配了一个 handleCgEvent
处理程序。
useEffect(() => {
window.addEventListener('message', handleCgEvent)
return () => window.removeEventListener('message', handleCgEvent)
}, [])
我正在渲染一个带有提交按钮的 iframe
,单击该按钮会发出 message
事件。
然后,当我单击 iframe
中的 sumbit 按钮时,handleCgEvent
处理程序将触发并应提取 ccFormDetails
的正确(更新的、已检测的)值。 (我可以在 React 组件树中看到正确填充)
const handleCgEvent = e => {
if (e.data === 'reload_cg') {
console.log('fail')
}
if (e.data['event_id'] === 'cg-success') {
console.log('success')
console.log('ccFormDetails1 ', ccFormDetails)
}
}
但我得到的是 {}
表示原始默认状态。
根据我对 React 的了解,这不应该发生。
我是否缺少 something/Does 事件处理混乱状态?
这里的问题是您正在使用安装组件时创建的 handleCgEvent
,并且 ccFormDetails
使用其默认值封装在其中。为了获得最新状态,您将不得不使用 useRef。类似于:
const [ccFormDetails, setCCFormDetails] = useState({})
const formRef = useRef();
formRef.current = ccFormDetails;
const handleCgEvent = e => {
if (e.data === 'reload_cg') {
console.log('fail')
}
if (e.data['event_id'] === 'cg-success') {
console.log('success')
console.log('ccFormDetails1 ', formRef.current)
}
}
useEffect(() => {
window.addEventListener('message', handleCgEvent)
return () => window.removeEventListener('message', handleCgEvent)
}, []);
如果您可以添加和删除事件侦听器,那么我将添加 [ccFormDetails]
作为依赖项,假设在其属性更改时重新创建整个对象。
要进一步阅读闭包中的陈旧值,这是一篇很棒的博客文章:https://dmitripavlutin.com/react-hooks-stale-closures/