反应useEffect无限循环获取数据axios

时间:2020-01-02 15:56:11

标签: reactjs axios fetch infinite-loop use-effect

此代码使我陷入无限循环。

我一直在尝试其他帖子中的一些解决方案,但是它们不起作用。

locationAddress是一个地址数组,我正在尝试使用Google Maps Geocode API获取坐标。

    const reducer = (state, action) => {
        switch (action.type) {
            case 'add':
                return [
                    ...state,
                    {
                        address: action.address,
                        name: action.name,
                        id: action.id
                    }
                ];
            case 'remove':
                return state.filter((_, index) => index !== action.index)
            default:
                return state;
        }
    }

    const [locationAddress, setLocationAddress] = useReducer(reducer, []);

    const [coordinates, setCoordinates] = useState([]);

    useEffect(() => {
        const fetchLocation = async () => {
            for(let i = 0; i < locationAddress.length; i++) {
                const response = await axios.get('https://maps.googleapis.com/maps/api/geocode/json', {
                    params: {
                        address: locationAddress[i].address,
                        key: 'MyAPIKey'
                    }

                })
                .then(response => {
                        setLocationAddress({locationAddress: response.data});
                        setCoordinates([...coordinates, {lat: response.data.results[0].geometry.location.lat, lng: response.data.results[0].geometry.location.lng}]);
                        }
                    )
                .catch(error => {
                    console.log(error)
                });
            }
        }
        fetchLocation();
    },[coordinates, locationAddress]);

2 个答案:

答案 0 :(得分:0)

其背后的原因是您的依赖项数组。基本上,axios调用完成后,您将使用setCoordinatessetLocationAddress更新依赖项,这将再次触发useEffect钩子的回调。

如果将[coordinates, locationAddress]用设置函数[setCoordinatessetLocationAddress]替换,它将按预期工作。

应该起作用的解决方案:

const [locationAddress, setLocationAddress] = useReducer(reducer, []);
const [coordinates, setCoordinates] = useState([]);

useEffect(() => {
    // ... removed definition for better representation in the answer

    fetchLocation();
}, [setCoordinates, setLocationAddress]);

由于缺少coordinateslocationAddress,您可能会收到一条警告消息,您可以通过// eslint-disable-next-line react-hooks/exhaustive-deps在依赖项数组之前的一行注释掉它们来禁用它。

希望对您有帮助!

答案 1 :(得分:-1)

您正在遍历locationAddress数组,调用api并在循环内更改同一数组。这导致了无限循环。为什么需要再次设置位置地址?如果您收到更多信息,请将其放在另一个数组中。