大家早上好
我刚完成React的培训,我想做一个练习项目。 首先,我只是在Firebase数据库中发布数据。 然后,我想获取数据以使用钩子(useState和useEffect)将其显示在react组件中。
问题是我用axios提取数据后最终陷入了经典的无限循环陷阱,但是我不知道如何通过依赖关系来停止它。
请在下面找到代码:
import React, {useState} from 'react'
import {useEffect} from 'react'
import classes from './Incomes.module.css'
import axios from '../../../axios'
import Button from '../../UI/Button/Button'
import Input from '../../UI/Input/Input'
const Incomes = (props) => {
const [inputValue, setInputValue] = useState('');
const [fetchedTypes, setFetchedTypes] = useState([]);
const onClickHandler = () => {
const type = {type: inputValue}
axios.post('/types.json', type)
.then(response => {
alert('ok c good');
})
.catch(error => console.log(error))
}
const onChangeHandler = (event) => {
setInputValue(event.target.value)
}
useEffect(() => {
axios.get('/types.json')
.then(response => {
let types = []
for(let key in response.data) {
types.push({...response.data[key], id: key})
}
console.log('types : ', types)
setFetchedTypes(prevFetchedTypes => [...prevFetchedTypes, types])
})
.catch(error => console.log(error))
console.log('fetchedtypes', fetchedTypes)
}, [fetchedTypes])
return (
<div className={classes.Incomes}>
<h2>Paramètres des entrées</h2>
<h3>Ajouter un type de revenu</h3>
<Input type="text" disabled={false} change={onChangeHandler} placeholder="Nom du champ"></Input>
<Button onClick={onClickHandler} type="Normal" clicked={onClickHandler}>Ajouter</Button>
<h3>Liste des types de revenus disponibles</h3>
</div>
)
}
export default Incomes;
当我使用控制台日志类型时,数据是正确的。 但是,当我使用控制台日志fetchedTypes时,它是一个空数组。
我找到了这篇文章,但是它都不起作用: React useEffect infinite loop fetch data axios
我不确定这是我使用useEffect的方式还是更新状态的方式,还是两者都有问题。
感谢您的帮助
祝你有美好的一天
答案 0 :(得分:0)
出现无限循环的原因是由于useEffect
和两个原因。
fetchedTypes
不是原始元素,而是某些对象/数组,因此每次总是不同。不要将它与useEffect一起使用。如果您想依赖对象,请肯特(Kent)推荐useDeepCompareEffect,但这里不需要。 setFetchedTypes(prevFetchedTypes => [...prevFetchedTypes, types])
您的useEffect将使用上面的行更新fetchedTypes,但它也应在fetchedTypes更改时运行。因此useEffect对其进行了更新,并且由于它的依赖项已更改,因此useEffect再次运行会导致无限循环。
可能的解决方案: 如果要在加载组件时获取数据,请将useEffect更改为此:
useEffect(() => {
axios.get('/types.json')
.then(response => {
let types = []
for(let key in response.data) {
types.push({...response.data[key], id: key})
}
console.log('types : ', types)
setFetchedTypes(types)
})
.catch(error => console.log(error))
console.log('fetchedtypes', fetchedTypes)
}, [])
但是,由于您具有点击处理程序,因此我假设您要在POST请求后更新数据。如果您的onClickHandler
返回了新创建的类型,请执行以下操作:
const onClickHandler = () => {
const type = {type: inputValue}
axios.post('/types.json', type)
.then(response => {
const newType = response.data;
const updatedTypes = [...types, newType]
setFetchedTypes(updatedTypes)
})
.catch(error => console.log(error))
}
注意: 我不知道您的类型的结构,因此我正在做一些假设,但这是个主意