我有react应用程序,我使用redux来管理状态。
假设会发生什么:
Redux持有一个包含_id
字符串的对象,在页面上我有一个useEffect
,它首先检查_id
是否为空字符串,然后调用异步函数onPlantTimelineMount()
使用_id
获取数据。当用户重新加载页面时,Redux状态默认为loaded,其中_id
是一个空字符串,因此调用useEffect
中的if语句,使用不同的异步函数ifUserRefreshPage()
获取该项,将该项调度到Redux状态,并且仅在调用onPlantTimelineMount()
之后。
问题:
ifUserRefreshPage()
成功获取数据并将其分配到Redux状态,但onPlantTimelineMount()
仍然使用ifUserRefreshPage()
调用之前的状态-这意味着_id
仍然是空字符串。
值得一提:
在ifUserRefreshPage()
中,我序列化获取的项(第38行),将其调度到Redux(第39行),console.log获取的项(图像中的第40行),并console.log Redux状态下的项(第41行),它仍然是空的!!怎么样?
x1c 0d1x的数据
验证码:
const currentPlant = useAppSelector(state => state.plants.currentPlant)
const plantUpdates = useAppSelector(state => state.plants.currentPlant.updates)
const reduxPlants = useAppSelector(state => state.plants.plants)
const location = useLocation();
const { show: showSnackbar, component: snackBar } = useSnackbar();
async function ifUserRefreshPage() {
setIsFetching(true)
const plantId = location.pathname.split('/')[2];
try {
console.log(`ifUserRefreshPage invoked`);
const plantResponse = await fetchPlantById(plantId, '1')
const serializedPlant = plantManager.serializePlant(plantResponse.data) // line 38
dispatch(setCurrentPlant(serializedPlant)) // line 39
console.log(serializedPlant); // line 40
console.log(currentPlant); // line 41
const gardenResponse = await fetchMyGarden('1')
dispatch(addPlants(plantManager.serializeGarden(gardenResponse.data)))
} catch (err) {
console.log(`error while running ifUserRefreshPage function` + err);
showSnackbar("Failed to load Timeline", "error");
} finally {
setIsFetching(false)
}
}
async function onPlantTimelineMount() {
setIsFetching(true)
console.log(`ifUserRefreshPage invoked`);
try {
const response = await fetchPlantUpdates(currentPlant._id!)
if (response.success) {
dispatch(setUpdatesToCurrentPlant(plantUpdateManager.serializeUpdatesArray(response.data)))
}
} catch (err) {
showSnackbar("Failed to load Timeline", "error");
} finally {
setIsFetching(false)
}
}
useEffect(() => {
async function start() {
if (!currentPlant._id) {
await ifUserRefreshPage()
}
await onPlantTimelineMount()
}
start()
},[])
字符串
1条答案
按热度按时间wbgh16ku1#
我console.log项目在Redux状态(第41行),它仍然是空的!!怎么样?
因为这是一个局部常数。它永远不会改变。这类似于更新状态不会更改局部变量的常见问题。Stack overflow on this topic,React docs on this topic
当你分派你的动作时,你更新了redux商店。这个更新的状态可以通过调用
store.getState()
来访问,尽管这通常不是你在react应用中直接做的事情。您已经调用了const currentPlant = useAppSelector(state => state.plants.currentPlant)
,它订阅了存储,因此状态的更改会导致组件重新呈现。当重新渲染发生时,将使用新值创建一个新的本地常量,但您在上一次渲染中的代码无法访问此常量。你的console.log(currentPlant);
从以前的渲染将永远只注销旧的值。由于您在不同的变量中确实有新值,因此我建议您使用它。例如,修改
ifUserRefreshPage
以返回新工厂:字符串
然后修改
onPlantTimelineMount
,这样你就可以传入工厂:型
并更新您的效果以连接两者:
型