Я создаю приложение, которое сильно зависит от анимации, и у меня возникают проблемы при работе с динамическими ссылками и пользовательскими хуками.
Итак, у меня есть настраиваемый хук, который добавляет прослушиватель событий щелчка, обрабатывает анимацию и возвращает ссылку.
const usePageChange = () => {
const node = useRef(null);
const tl = useMemo(() => gsap.timeline({ paused: true }), []);
useEffect(() => {
// Set GSAP timeline
// omited for the sake of brevety
return () => {
tl.kill();
};
}, []);
useEffect(() => {
const set = (ev) => {
ev.preventDefault();
tl.play();
};
const { current } = node;
current.addEventListener('click', set);
return () => {
current.removeEventListener('click', set);
};
}, [tl]);
return node;
};
Это отлично работает для refs
, которые не являются динамическими:
const Home = () => {
const elementRef = usePageChange();
return (
<div className='slides'>
<img
alt='some alt'
src='/public/someimage.jpg'
ref={elementRef}
/>
</div>
);
};
Но мне не удалось найти способ сделать это с помощью динамического refs
без нарушения Правила хуков.
Это то, что я пробовал (упрощенно), но, очевидно, неправильно. React Hook нельзя вызвать внутри обратного вызова: useRef(projects.map(() => usePageChange()));
const Home = () => {
const projects = useSelector((state) => state.projects.data);
const elementsRef = useRef(projects.map(() => usePageChange()));
return (
<div className='slides'>
{projects.map((project, i) => (
<img
alt={`${project.image_alt}`}
src={`/public/${project.image_path}`}
ref={elementsRef[i]}
/>
))}
</div>
);
};
Что мне действительно нужно, так это способ каким-то образом перебрать длину проекта и динамически вызвать хук usePageChange
.
На данный момент я не знаю, лучше ли просто добавить событие щелчка непосредственно к каждому динамическому элементу и обработать анимацию внутри компонента.