为何useEffect清理函数在应用启动时执行?query未变更
为什么useEffect的清理函数在应用启动时就执行了?
你遇到的是React**严格模式(Strict Mode)**在开发环境下的特殊行为——它会主动重复执行组件的挂载逻辑,包括调用useEffect,并且在第一次执行后立即触发清理函数,随后再次运行useEffect。这是React的调试机制,用来帮你排查未正确清理的副作用(比如未取消的网络请求、遗留的定时器),生产环境不会出现这个现象。
结合你的代码来看:
你的query初始值固定为"interstellar",没有变化,但在开发环境的Strict Mode下,React会按以下流程执行:
- 第一次执行
useEffect,发起网络请求 - 立即调用清理函数(
controller.abort()),中止第一次请求 - 再次执行
useEffect,重新发起请求
这就是你看到启动时清理函数执行的原因,并非你的代码逻辑错误,只是开发环境的调试行为。
你可以通过暂时移除根组件的<React.StrictMode>包裹来验证这一点,此时清理函数只会在组件卸载或者query变化时执行。
你的代码片段:
const [movies, setMovies] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(""); const [query, setQuery] = useState("interstellar"); useEffect(() => { const controller = new AbortController(); async function fetchMovies() { try { setError(""); setIsLoading(true); const res = await fetch( `http://www.omdbapi.com/?apikey=${KEY}&s=${query}`, { signal: controller.signal } ); if (!res.ok) throw new Error("Failed to fetch movies"); const data = await res.json(); if (data.Response === "False") throw new Error("No movies found"); setMovies(data.Search); } catch (err) { console.error(err.message); if (err.name !== "AbortError") setError(err.message); } finally { setIsLoading(false); } } if (!query) { setMovies([]); setError(""); return; } fetchMovies(); return () => controller.abort(); }, [query]);
内容的提问来源于stack exchange,提问作者Ilya Turchenko
相关产品推荐
相关产品推荐

