我正在尝试从 firebase 加载一些图像,并让它们使用机车滚动反应模块水平滚动。但是,每当我添加下面的 useEffect 部分来初始化机车滚动时,我都会收到以下错误:
我已遵循 LocomotiveScroll 网站和 GitHub 页面上的所有说明,还查看了其他示例,但似乎无法弄清楚。或者甚至可能我错过了一些东西。
import React, { useEffect } from "react";
import useFirestore from "../../Hooks/useFirestore";
import "./Astro.css";
import LocomotiveScroll from "locomotive-scroll";
//<a class="gallery__item-link">explore</a>
const Astro = (props) => {
const { docs } = useFirestore("astro");
let i = 1;
const scrollReff = React.createRef();
useEffect(() => {
const scroll = new LocomotiveScroll({
el: scrollReff.current,
smooth: true,
direction: "horizontal"
});
});
return (
<div>
{docs &&
docs.map((doc) => (
<div key={doc.id}>
<div ref={scrollReff}>
<div className="content">
<div className="gallery">
<figure className="gallery__item">
<div className="gallery__item-img">
<div class="gallery__item-img">
<div
class="gallery__item-imginner"
>
<img src={doc.url} alt={doc.description} />
</div>
</div>
</div>
<figcaption className="gallery__item-caption">
<h2
className="gallery__item-title"
data-scroll
data-scroll-speed="1"
>
{doc.title}
</h2>
<span className="gallery__item-number">{"0" + i++}</span>
</figcaption>
</figure>
</div>
</div>
</div>
</div>
))}
</div>
);
};
export default Astro;
从我的角度来看,你需要添加一个条件,因为这个问题与异步有关。 当此变量不存在时,在 useEffect 中您将使用scrollRef。为什么?因为在渲染中,您正在调节文档是否存在。如果您了解 useEffect 的工作原理,您就会明白第一次渲染 useEffect 没有找到此变量。
const Astro = (props) => {
...
useEffect(() => {
if(!docs) return;
const scroll = new LocomotiveScroll({
...
});
});
我遇到了同样的问题,然后意识到我忘记在
<main data-scroll-container ref={containerRef}>
中添加 <LocomotiveScrollProvider>
。
像这样;
<LocomotiveScrollProvider
options={{smooth: true,}}
watch={[]}
containerRef={containerRef}
>
<main data-scroll-container ref={containerRef}>
<Component {...pageProps} />
</main>
</LocomotiveScrollProvider>
React.createRef() 是异步的,因此如果您尝试在
useEffect
中访问它,它将返回 null
。这意味着当您在 scrollRef.current
内部调用 useEffect
时,您还没有为其分配任何真实实例。
我遇到了同样的问题,并通过将
data-scroll-container ref={containerRef}
添加到 LocomotiveScrollProvider
的第一个子项来解决它。这解决了我的问题。
"use client";
import { usePathname } from "next/navigation";
import * as React from "react";
import { LocomotiveScrollProvider } from "react-locomotive-scroll";
interface AppLayoutProps {
children: React.ReactNode;
}
export default function AppLayout({ children }: AppLayoutProps) {
const pathname = usePathname();
const containerRef = React.useRef(null);
return (
<LocomotiveScrollProvider
options={{
smooth: true,
}}
watch={[pathname, children]}
location={pathname}
containerRef={containerRef}
onLocationChange={(scroll: {
scrollTo: (
arg0: number,
arg1: { duration: number; disableLerp: boolean },
) => any;
}) => scroll.scrollTo(0, { duration: 0, disableLerp: true })}
>
<main
data-scroll-container
ref={containerRef}
className="w-screen flex-1"
>
{children}
</main>
</LocomotiveScrollProvider>
);
}