当我收到数据时,我使用useEffect钩子通过调用另一个函数getData从数据库中获取数据。
const [employees, setEmployees] = useState([])
const [shownEmployees, setShownEmployees] = useState([])
const [nbrPages, setNbrPages] = useState(0)
const getData = () => {
axios.request(options).then((response) => {
setEmployees(response.data)
setShownEmployees(response.data.slice(0, nbrItems))
response.data.length%nbrItems > 0 ? setNbrPages((response.data.length/nbrItems)+1) : setNbrPages(response.data.length/nbrItems)
console.log(nbrPages)
}).catch((error) => console.log(error))
for(let i=0;i<nbrPages;i++){
pages_temp.push(i)
}
console.log(pages_temp.length)
setPages(pages_temp)
}
useEffect(() => {
getData()
},[])
问题nbrPages
始终为0,但是当我将employees
用作useEffect作为依赖项时,useEffect执行了很多次,但是这次nbrPages
被bieng计算。谁能解释这种行为,我已经尝试了所有事情。本质上,我想了解为什么当我将useEffect
作为依赖项时employees
会无限执行,employees
在什么时候发生变化,从而触发useEffect钩子。
答案 0 :(得分:1)
之所以会这样,是因为您正在通过getData方法更新状态下的employees
。
setEmployees(response.data)
这正在更新employees
,并且每次员工更新时都会调用useEffect。
更新:看来您的问题不在于useEffect。您可以调试代码,看看此时发生了什么,
response.data.length%nbrItems > 0 ? setNbrPages((response.data.length/nbrItems)+1) : setNbrPages(response.data.length/nbrItems)
您可以将此部分重写为
console.log(response.data.length);
console.log(nbrItems);
console.log(response.data.length % nbrItems);
if(response.data.length % nbrItems) {
let temp = (response.data.length/nbrItems)+1;
console.log('Temp:', temp);
setNbrPages(temp);
} else {
console.log('Inside else block');
let temp = response.data.length/nbrItems;
console.log('Inside else temp:', temp);
setNbrPages(temp);
}
然后查看控制台日志是什么,并确定您的值是否正确。
Update2::您可以使用另一个useEffect解决问题。
const [employees, setEmployees] = useState([])
const [shownEmployees, setShownEmployees] = useState([])
const [nbrPages, setNbrPages] = useState(0)
const getData = () => {
axios.request(options).then((response) => {
setEmployees(response.data)
setShownEmployees(response.data.slice(0, nbrItems))
response.data.length%nbrItems > 0 ? setNbrPages((response.data.length/nbrItems)+1) : setNbrPages(response.data.length/nbrItems)
console.log(nbrPages)
}).catch((error) => console.log(error))
}
useEffect(() => {
getData()
},[])
useEffect(() => {
for(let i=0;i<nbrPages;i++){
pages_temp.push(i)
}
console.log(pages_temp.length)
setPages(pages_temp)
},[nbrPages]);
答案 1 :(得分:0)
应用清理功能后呈现useEffect的关键
解决方案:
const [employees, setEmployees] = useState([])
const [shownEmployees, setShownEmployees] = useState([])
const [nbrPages, setNbrPages] = useState(0)
const [mounted, setMounted] = useState(true); //Add this state helping with clean see below in useEffect
const getData = () => {
axios.request(options).then((response) => {
setEmployees(response.data)
setShownEmployees(response.data.slice(0, nbrItems))
response.data.length%nbrItems > 0 ? setNbrPages((response.data.length/nbrItems)+1) : setNbrPages(response.data.length/nbrItems)
console.log(nbrPages)
}).catch((error) => console.log(error))
for(let i=0;i<nbrPages;i++){
pages_temp.push(i)
}
console.log(pages_temp.length)
setPages(pages_temp)
}
useEffect(() => {
if (mounted){
getData()
}
return ()=>{
setMounted(false); // Cleanup function so that function called inside renders once
}
},[mounted])//useEffect dependency is the state added that is **mounted**
调试API调用技术的功能
暂时避免使用axios创建实例,直到可以追溯错误为止
暂时避免使用内部逻辑将内容保存为状态,只需console.log记录您的内容并查看发生了什么情况
一旦建立了1和2,您就知道自己处在正确的轨道上,现在您知道逻辑上存在错误,然后从那里修复
const getData = async() => {
const {data} = await axios.get(url)
console.log(data)
//Then if this console.log bring you back data that you want
//now start rebuilding your logic piece by piece so that if
//something bugs out you know that the previous step for sure is
//not the one cause you have validated it
}
因此,如果您可以执行此调试过程,那么您将走在正确的轨道上
答案 2 :(得分:0)
useEffect
当提供prop / state作为参数时,其工作原理与componentDidUpdate
完全相同,这意味着每次对此prop / state进行更改时,它将呈现(如果您通过employees
作为依赖项,这意味着它将首先执行,并且在每次axios调用之后,该值都会更新,这意味着它将一次又一次触发useEffect。componentDidMount
,这意味着它在开始时只会被触发一次。