私の Gatsby サイトでは、すべてのページで同じ GSAP タイムラインを使用しているため、DRY を維持したいと考えており、レイアウト コンポーネントにタイムラインをその順序で含めることを考えています。
しかし、forwardRef を使用して子とレイアウトの間で必要な参照を渡す方法がわかりません。
要するに、ページとレイアウトの間のsectionsRef部分の扱い方がわかりません。sectionRef はページ コンテンツ (子) に依存しますが、レイアウト内のタイムラインで必要です。
これら2つの間でsectionRefを共有するにはどうすればよいですか(私は多くのことを試しましたが、常にエラーにつながります)?
レイアウトに参照がないコードサンドボックスは次のとおりです: https://codesandbox.io/s/jolly-almeida-njt2e?file=/src/pages/index.js
そして、レイアウト内の参照を含むサンドボックス: https://codesandbox.io/s/pensive-varahamihira-tc45m?file=/src/pages/index.js
これが私のファイルの簡略版です: Layout.js
export default function Layout({ children }) {
const containerRef = useRef(null);
const sectionsRef = useRef([]);
sectionsRef.current = [];
useEffect(() => {
gsap.registerPlugin(ScrollTrigger);
const scrollTimeline = gsap.timeline();
scrollTimeline.to(sectionsRef.current, {
x: () =>
`${-(
containerRef.current.scrollWidth -
document.documentElement.clientWidth
)}px`,
ease: 'none',
scrollTrigger: {
trigger: containerRef.current,
invalidateOnRefresh: true,
scrub: 0.5,
pin: true,
start: () => `top top`,
end: () =>
`+=${
containerRef.current.scrollWidth -
document.documentElement.clientWidth
}`,
},
});
}, [containerRef, sectionsRef]);
return (
<div className="slides-container" ref={containerRef}>
{children}
</div>
);
}
index.js (ページ)
import { graphql } from 'gatsby';
import React, { forwardRef } from 'react';
import SectionImage from '../components/sections/SectionImage';
import SectionIntro from '../components/sections/SectionIntro';
import SectionColumns from '../components/sections/SectionColumns';
const HomePage = ({ data: { home } }, sectionsRef) => {
const { sections } = home;
const addToRefs = (el) => {
if (el && !sectionsRef.current.includes(el)) {
sectionsRef.current.push(el);
}
};
return (
<>
{sections.map((section) => {
if (section.__typename === 'SanitySectionIntro') {
return (
<SectionIntro key={section.id} section={section} ref={addToRefs} />
);
}
if (section.__typename === 'SanitySectionImage') {
return (
<SectionImage key={section.id} section={section} ref={addToRefs} />
);
}
if (section.__typename === 'SanitySectionColumns') {
return (
<SectionColumns
key={section.id}
section={section}
ref={addToRefs}
/>
);
}
return '';
})}
</>
);
};
export default forwardRef(HomePage);
export const query = graphql`
query HomeQuery {
// ...
}
`;
どんな手がかりも大歓迎です:)