React useEffect 无限循环获取数据 axios

Sér*_*eia 3 infinite-loop fetch reactjs axios 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]);
Run Code Online (Sandbox Code Playgroud)

nor*_*ial 5

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

如果您替换[coordinates, locationAddress]为 setter 函数 [ setCoordinates, setLocationAddress] ,那么它将按预期工作。

应该工作的解决方案:

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

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

    fetchLocation();
}, [setCoordinates, setLocationAddress]);
Run Code Online (Sandbox Code Playgroud)

由于丢失coordinates,您可能会收到一条警告消息locationAddress,您可以// eslint-disable-next-line react-hooks/exhaustive-deps在依赖项数组之前的一行注释将其禁用。

我希望这有帮助!