为什么 React.useEffect() 在挂载组件后不执行



我正在尝试获取时间表。我将零数组作为第二个参数传递给useEffect(),所以它应该在渲染后执行,但不知何故它甚至没有执行一次。有人能解释一下我的代码是怎么回事吗?提前感谢!

这里是我调用useEffect (log "Fetch被执行!")不打印)

import { useEffect, useState } from "react";
import { ITimetable } from "../models";
export function useTimetables() {
const [timetables, setTimetables] = useState<ITimetable[]>([])
async function fetchTimetables() {      
try {
const response = await axios.get<ITimetable[]>("localhost:8080/api/v1/timetable/all")
setTimetables(response.data)
}
catch (err: unknown) {
const error = err as AxiosError
console.log(error.message)
}
}
useEffect( () => { 
fetchTimetables()
console.log("Fetch was performed!")
}, [])
return { timetables }
}

下面是useActivities()调用

的组件
import { Timetable } from "../components/Timetable";
import { useTimetables } from "../hooks/timetables";
export function MainPage() {
const { timetables } = useTimetables()

return (
<>
<NavigationPanel></NavigationPanel>
<div className="timetables-view">
{/* { timetables.map( timetable => <Timetable timetable={ timetable }></Timetable> ) } */}
<Timetable timetable={ timetables[0] }/>
</div>
</>
);
}

时间表组件

import { ITimetable } from "../models";
import { useActivities } from "../hooks/activities";
import { Activity } from "./Activity";
import "../css-components/Timetable.css";
interface TimetalbeProps {
timetable: ITimetable
}
export function Timetable({ timetable }: TimetalbeProps) {
const { activities, loading, error } = useActivities(timetable.id)
return (
<div className="activity-container">
{ loading && <div>Loading...</div>}
{ error && <div>{ error }</div>}
{ activities.map(
activity => <Activity activity={ activity }/> 
)}
</div>
);
}

带有空依赖数组([])的useEffect钩子只在组件初始呈现后执行一次。当一些状态或道具发生变化时,它被用来执行任何不需要重新执行的副作用。

在你的代码中,useTimetables自定义钩子是从MainPage组件调用的,它触发了useTimetables钩子中定义的useEffect钩子的执行。调用fetchTimetables函数,然后调用setTimetables函数,用获取的数据更新时间表状态变量。

因为useEffect钩子有一个空的依赖数组,它将不会被再次执行,即使时间表状态变量后来改变了。这意味着fetch时间表函数将不会被再次调用,并且控制台日志消息"Fetch已执行!"不会再打印。

如果你想在某些依赖项发生变化时(比如道具或状态变量)重新获取时间表数据,你需要在useEffect钩子的依赖项数组中包含该依赖项。例如,如果您想在加载状态变量改变时重新获取时间表数据,您可以这样编写useEffect钩子:

useEffect(() => {
if (loading) {
fetchTimetables();
console.log("Fetch was performed!");
}
},
[loading]);

这将确保在加载状态变量发生变化时再次执行fetch时间表函数

相关内容