axios请求不断返回两次未定义和两次数据

我正在尝试使用 Axios 在自定义 reactjs 挂钩上获取 api。我一直得到两倍的未定义响应,然后是成功获取数据的两倍。未定义破坏了我的应用程序。

顺便说一句,我正在从 randomuser api 获取。

import axios from "axios";
import { useState, useEffect } from "react"

export const useFetch = (url) => {
    const [loading, setLoading] = useState(false);
    const [data, setData] = useState([]);
    const [error, setError] = useState('')

    const getData = () => {
        setLoading(true)
        try {
            axios.get(url)
                .then(response => setData(response.data));
                setLoading(false)
          } catch (error) {
            setError(error)
          }
    };

    useEffect(() => {
        getData()
    }, [url])

    return {loading, data, error}
}

尝试在这里使用它并映射它

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useFetch } from '../custom_hooks/useFetch';

const PersonDetails = () => {

    const { loading, data , error } = useFetch('https://randomuser.me/api?results=20');
    const { results } = data;
    const { id } = useParams();

    const [person, setPerson] = useState({})

    useEffect(() => {
        const newPerson = results?.find(person => person.login.uuid === parseInt(id))
        setPerson(newPerson)
        console.log(newPerson)
    }, [])

    return (
        <div>
            {person.name.first}
        </div>
    )
}

export default PersonDetails

这是我实际上正在尝试做的事情,但现在因为它是未定义的,我得到无法读取未定义的属性......

stack overflow Axios request keeps returning twice undefined and twice the data
原文答案

答案:

作者头像

当效果运行时:

  1. setLoading(true)
    2.发送ajax请求
  2. setLoading(false)

稍后,Ajax 响应会到达您:

  1. setData(response.data)

由于您依赖 loading 来确定是否设置了 data ,因此它会中断。

你可以做两件事:

  1. setLoading(false) 移动到 then 回调中,以便在您拥有 setData(response.data) 之前不会设置它
  2. 完全摆脱 loading 并将您的逻辑基于 dataundefined 或具有不同的值。
作者头像

1.你应该在useEffect里面定义getData函数,或者把它传入依赖数组,然后用usecallback包装函数,避免不必要的重新渲染。
2.你应该在取消的情况下使用abortcontroller,并在使用效果中具有清理功能。 (这种情况下最好在useeffect中定义getdata body)

    useEffect(() => {
        const controller = new AbortController();
        const getData = async () => {
           setLoading(true)
           try {
                await axios.get(url, {signal: controller.signal})
                .then(response => setData(response.data));
               } catch (error) {
                setError(error)
               }
            }
        getData()
        return()=>controller.abort()
     },[url]}

您可以在以下 url 中阅读有关使用钩子获取数据的更多信息,以及在哪里设置加载和其他需要的状态。 https://www.robinwieruch.de/react-hooks-fetch-data/

作者头像

以防万一,这个解决方案帮助了我: https://github.com/axios/axios/issues/2825#issuecomment-883635938

"The problem in my case was caused by React development server. The strict mode in react caused the issue! I had to remove the strict mode This solved the problem of sending double requests! The strict mode checks are only run in development mode. Doc: [https://reactjs.org/docs/strict-mode.html](https://reactjs.org/docs/strict-mode.html) "