React 的 exhaustive-deps linter 规则在一种情况下触发但在另一种情况下没有触发?
React's exhaustive-deps linter rule triggered in one case but not the other?
我想将此 Code Sandbox https://codesandbox.io/s/lx947qjv0z 改编为我自己的 React 应用程序。我试过简单地 useGoogleMap.js
,
import { useEffect, useState, useRef } from "react";
import GoogleMapsApiLoader from "google-maps-api-loader";
const apiKey = "AIzaSyCVBthtEmWi0Ul8mejDQrBlOULXB1kTB3I";
const eventsMapping = {
onCenterChanged: ["center_changed", map => map.getCenter()],
onBoundsChanged: ["bounds_changed", map => map.getBounds()]
};
export default function useGoogleMap({ zoom, center, events }) {
const [mapState, setMapState] = useState({ loading: true });
const mapRef = useRef();
useEffect(() => {
GoogleMapsApiLoader({ apiKey }).then(google => {
const map = new google.maps.Map(mapRef.current, { zoom, center });
Object.keys(events).forEach(eventName =>
map.addListener(eventsMapping[eventName][0], () =>
events[eventName](eventsMapping[eventName][1](map))
)
);
setMapState({ maps: google.maps, map, loading: false });
});
}, []);
return { mapRef, ...mapState };
}
以下内容(因为我认为我不需要 events
):
import {useState, useEffect, useRef } from 'react';
import GoogleMapsApiLoader from 'google-maps-api-loader';
const apiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;
export default function useGoogleMap(options) {
const [mapState, setMapState] = useState();
const mapRef = useRef();
useEffect(() => {
GoogleMapsApiLoader({ apiKey }).then(google => {
const map = new google.maps.Map(mapRef.current, options);
setMapState({ maps: google.maps, map });
});
}, [options]);
return { mapRef, ...mapState };
}
在我自己的代码中,如果我从作为第二个参数传递给 useEffect()
的依赖项数组中省略 options
,我会收到 linter 警告:
React Hook has a missing dependency: 'options'
令我困惑的是:为什么原来的Sandbox代码没有这样的警告? zoom
和 center
不是也依赖于它在 useEffect()
中的效果吗?
你 post 的那个 codesandbox 也收到了错误
这篇文章可能会有所帮助 https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies
本质上,useEffect 无法立即访问选项。所以你需要像这样将选项作为参数传递给 useEffect....
export default function useGoogleMap(options) {
const [mapState, setMapState] = useState({ loading: true });
const mapRef = useRef();
useEffect((options) => {
GoogleMapsApiLoader({ apiKey }).then(google => {
const map = new google.maps.Map(mapRef.current, options);
setMapState({ maps: google.maps, map, loading: false });
});
}, []);
return { mapRef, ...mapState };
}
这将消除您的错误!
我想将此 Code Sandbox https://codesandbox.io/s/lx947qjv0z 改编为我自己的 React 应用程序。我试过简单地 useGoogleMap.js
,
import { useEffect, useState, useRef } from "react";
import GoogleMapsApiLoader from "google-maps-api-loader";
const apiKey = "AIzaSyCVBthtEmWi0Ul8mejDQrBlOULXB1kTB3I";
const eventsMapping = {
onCenterChanged: ["center_changed", map => map.getCenter()],
onBoundsChanged: ["bounds_changed", map => map.getBounds()]
};
export default function useGoogleMap({ zoom, center, events }) {
const [mapState, setMapState] = useState({ loading: true });
const mapRef = useRef();
useEffect(() => {
GoogleMapsApiLoader({ apiKey }).then(google => {
const map = new google.maps.Map(mapRef.current, { zoom, center });
Object.keys(events).forEach(eventName =>
map.addListener(eventsMapping[eventName][0], () =>
events[eventName](eventsMapping[eventName][1](map))
)
);
setMapState({ maps: google.maps, map, loading: false });
});
}, []);
return { mapRef, ...mapState };
}
以下内容(因为我认为我不需要 events
):
import {useState, useEffect, useRef } from 'react';
import GoogleMapsApiLoader from 'google-maps-api-loader';
const apiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;
export default function useGoogleMap(options) {
const [mapState, setMapState] = useState();
const mapRef = useRef();
useEffect(() => {
GoogleMapsApiLoader({ apiKey }).then(google => {
const map = new google.maps.Map(mapRef.current, options);
setMapState({ maps: google.maps, map });
});
}, [options]);
return { mapRef, ...mapState };
}
在我自己的代码中,如果我从作为第二个参数传递给 useEffect()
的依赖项数组中省略 options
,我会收到 linter 警告:
React Hook has a missing dependency: 'options'
令我困惑的是:为什么原来的Sandbox代码没有这样的警告? zoom
和 center
不是也依赖于它在 useEffect()
中的效果吗?
你 post 的那个 codesandbox 也收到了错误
这篇文章可能会有所帮助 https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies
本质上,useEffect 无法立即访问选项。所以你需要像这样将选项作为参数传递给 useEffect....
export default function useGoogleMap(options) {
const [mapState, setMapState] = useState({ loading: true });
const mapRef = useRef();
useEffect((options) => {
GoogleMapsApiLoader({ apiKey }).then(google => {
const map = new google.maps.Map(mapRef.current, options);
setMapState({ maps: google.maps, map, loading: false });
});
}, []);
return { mapRef, ...mapState };
}
这将消除您的错误!