【问题标题】:How come my state is not updated after fetching data?为什么我的状态在获取数据后没有更新?
【发布时间】:2021-01-30 20:35:03
【问题描述】:

大家早上好,

我刚刚完成了 React 培训,我想制作一个项目来练习。 首先,我只是在 firebase 数据库中发布数据。 然后,我想获取数据以使用钩子(useState 和 useEffect)将其显示在反应组件中。

问题是我在使用 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 的方式或我更新状态的方式有关,或两者兼而有之。

感谢您的帮助

祝你有美好的一天

【问题讨论】:

    标签: reactjs axios react-hooks use-effect


    【解决方案1】:

    你得到一个无限循环的原因是你的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)
    }, [])
    
    • 忽略任何 lint 警告。一个空的依赖数组意味着它只会在组件渲染时运行一次。

    但是由于您有一个点击处理程序,我假设您想在 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))
    }
    

    注意: 我不知道你的类型的结构,所以我正在处理假设,但这就是想法

    【讨论】:

    • 谢谢,它正在工作。实际上,当我在使用效果后控制台日志时,数据是正确的,我试图弄清楚为什么(在钩子中设置的循环)......
    猜你喜欢
    • 2020-04-14
    • 2020-07-31
    • 2017-01-25
    • 1970-01-01
    • 2021-08-04
    • 2021-09-02
    • 1970-01-01
    • 2022-01-16
    • 2021-10-05
    相关资源
    最近更新 更多