在我的 React 应用程序中,我使用的是 FullCalendar.io。关于设置 Loading 状态,文档有点稀疏(并且不是 React 特有的):https://fullcalendar.io/docs/loading
如果我有:
const [loading, setLoading] = useState(false)
...
{loading ? <Spinner /> : null}
<FullCalendar
plugins={[ dayGridPlugin ]}
initialView="dayGridMonth"
loading={e => setLoading(e)} // With this line, it continually reloads the data source
eventSources={[{
url: '/api/calendar',
method: 'GET',
}]}
/>
如果我注释掉上面的加载行,它会完美工作,但如果我想在加载时触发指示器,则会将数据加载放入无限循环中。
就像每当发生任何变化时,日历都会重新获取数据。如果我这样做,它也会做同样的事情:
loading={loadingFunction}
并且:
function loadingFunction (boolean) {
setLoading(boolean)
}
请注意,如果我使用initialEvents,它不会执行此操作,但这提供的灵活性较差。 (然后加载按预期进行。)但是使用事件或事件源,它会将其放入加载循环中。
看来将其包装在 useCallback 中:
const loadingFunction = useCallback((boolean) => {
setLoading(boolean)
},[setLoading])
并将 FullCalendar 包装在 useMemo 中:
const fullCalendar = useMemo( () => <FullCalendar ... /> , [loadingFunction] )
解决了这个问题。希望我没有发现任何缺点......
我知道这个问题很老了,但我认为值得回答。 Ben 在 CA 的答案对我不起作用(React 18)。
有效的是使用 ref 功能手动附加事件侦听器并添加/删除类名。
在组件主体中
const ref = React.useRef<FullCalendar | undefined>();
const calendarLoading = React.useRef<HTMLDivElement | null>(null);
useEffect(() => {
ref.current?.getApi().on("loading", (isLoading) => {
if (isLoading) {
calendarLoading.current?.classList.add("block");
calendarLoading.current?.classList.remove("hidden");
return;
} else {
calendarLoading.current?.classList.remove("block");
calendarLoading.current?.classList.add("hidden");
}
});
}, [ref.current, calendarLoading.current]);
在你的渲染中
<div ref={calendarLoading} className={"flex"}>
<Loader2Icon className="h-4 w-4 animate-spin" />
</div>
<FullCalendar
plugins={[ dayGridPlugin ]}
initialView="dayGridMonth"
loading={e => setLoading(e)} // With this line, it continually reloads the data source
eventSources={[{
url: '/api/calendar',
method: 'GET',
}]}
ref={ref}
/>