gpt4 book ai didi

javascript - 为什么我的函数无法读取组件状态的实际值?

转载 作者:行者123 更新时间:2023-12-02 22:45:01 25 4
gpt4 key购买 nike

对于一个学校项目,我的小组正在构建一个通过数据库调用填充城市数据的表。表格组件的骨架是这样的:

import React, { useState } from 'react' 

function Table(props) {
const [ cities, setCities ] = useState([])
const [ pageNum, setPageNum ] = useState(0)

useEffect(()=> { // this sets up the listener for the infinite scroll
document.querySelector(".TableComponent").onscroll = () => {
if (Math.ceil(table.scrollHeight - table.scrollTop) === table.clientHeight) showMoreRows()
}
//initial fetch
fetchData(0)
},[])

async function showMoreRows() {
console.log("Show more rows!")
await fetchData(pageNum)
}

async function fetchData(page) {
// some code, describing fetching
// EDIT2 start
console.log(pageNum)
// EDIT2 end
const jsonResponse = await {}// THE RESPONSE FROM THE FETCH
if(page) {
setCities([...cities, ...jsonResponse])
console.log("page is true", page)
setPageNum(pageNum + 1)
} else {
console.log("page is false", page) // this always runs and prints "page is false 0"
setCities([...cities, ...jsonResponse])
setPageNum(1)
}
}


return <div className="TableComponent"> { pageNum }
<!-- The rest of the component -->
</div>
}

该表具有“无限滚动”功能,因此当您滚动到页面底部时,它会打印“显示更多行!” 并运行fetchData(pageNum) 获取更多数据。此时,在初始获取之后,pageNum 变量应该为 1 或更大,但由于某种原因,该函数的行为就好像它是 0。我将 pageNum -JSX 中显示的变量,我可以看到它是 1,但当我运行它时,它仍然打印出 “page is false 0”

当我尝试用谷歌搜索这个问题时,似乎唯一相似的事情可能是我在使用 setPageNum (重绘之前)后过早尝试读取 useState-variable,但就目前情况而言,这里并非如此我可以看到。我在两次尝试之间给了它足够的时间,它总是说 pageNum 为零。

关于我做错了什么,以及这有什么意义,有什么想法吗?

感谢您的帮助!

编辑:刚刚尝试了我写的代码,它似乎有效 - 但是我拥有的完整代码不起作用。即使上面的代码可能有效,任何人对与此相关的问题有任何想法吗?

EDIT2:我在 fetchData 函数中添加了一个 console.log(pageNum) ,并进行了一些测试,似乎无论我放入初始值useState(VALUE) 中是正在打印的内容。这对我来说没有意义。帮助。

EDIT3:添加了等待,实际代码中已经有了

EDIT4:我已经尝试了一段时间,但意识到当我使用 React 时,我可以将滚动监听器移动到 JSX 区域,然后由于某种原因它起作用了。现在可以了。无法真正将任何答案标记为正确的答案,但问题在某种程度上得到了解决。

感谢所有试图提供帮助的人,非常感谢。

最佳答案

发生过时问题是因为 React 不知道您对组件状态的依赖关系。

例如,useEffect 确保每次滚动时都会调用初始渲染范围内的 showMoreRows 值。 showMoreRows 的此副本引用了 pageNum 的初始值,但该值“卡住”在 closure 中。与函数一起变化,并且不会随着组件状态的变化而变化。因此滚动监听将不起作用,因为它需要知道 pageNum 的当前状态。

您可以使用 callbacks 解决问题“hookify” showMoreRowsfetchData 并声明它们对组件状态的依赖。然后,您必须声明 useEffect 对这些回调的依赖并使用 clean-up function处理多次调用的效果。

它看起来像这样(我还没有尝试运行代码):

import React, { useState } from 'react' 

function Table(props) {
const [ cities, setCities ] = useState([])
const [ pageNum, setPageNum ] = useState(0)

useEffect(()=> {
// Run this only once by not declaring any dependencies
fetchData(0)
}, [])

useEffect(()=> {
// This will run whenever showMoreRows changes.

const onScroll = () => {
if (Math.ceil(table.scrollHeight - table.scrollTop) === table.clientHeight) showMoreRows()
};

document.querySelector(".TableComponent").onscroll = onScroll;

// Clean-up
return () => document.querySelector(".TableComponent").onscroll = null;
}, [showMoreRows])

const showMoreRows = React.useCallback(async function () {
console.log("Show more rows!")
await fetchData(pageNum)
}, [fetchData, pageNum]);

const fetchData = React.useCallback(async function (page) {
// some code, describing fetching
// EDIT2 start
console.log(pageNum)
// EDIT2 end
const jsonResponse = await {}// THE RESPONSE FROM THE FETCH
if(page) {
setCities([...cities, ...jsonResponse])
console.log("page is true", page)
setPageNum(pageNum + 1)
} else {
console.log("page is false", page) // this always runs and prints "page is false 0"
setCities([...cities, ...jsonResponse])
setPageNum(1)
}
}, [setCities, cities, setPageNum, pageNum]);

return <div className="TableComponent"> { pageNum }
<!-- The rest of the component -->
</div>
}

关于javascript - 为什么我的函数无法读取组件状态的实际值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58440954/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com