Code Review. Scroll by using RAF
ilyasidorchik
jsx
10 months ago
1.7 kB
22
Indexable
import React, { useEffect, useRef, useCallback, useState } from 'react';
import Item from './Item';
import './style.css';
export default function App() {
const [count, setCount] = useState(0);
const topRef = useRef<HTMLDivElement>(null);
const rafIdRef = useRef<number | null>(null);
const updatePos = useCallback((y: number) => {
const el = topRef.current;
if (!el) return;
if (y > 100) {
// меняем только композитное свойство
el.style.willChange = 'transform';
el.style.transform = `translateY(${y}px)`;
} else {
el.style.transform = 'translateY(0)';
el.style.willChange = '';
}
}, []);
useEffect(() => {
const onScroll = () => {
const y = window.scrollY;
if (rafIdRef.current != null) cancelAnimationFrame(rafIdRef.current);
rafIdRef.current = requestAnimationFrame(() => updatePos(y));
};
window.addEventListener('scroll', onScroll, { passive: true });
// начальное положение
updatePos(window.scrollY);
return () => {
window.removeEventListener('scroll', onScroll);
if (rafIdRef.current != null) cancelAnimationFrame(rafIdRef.current);
};
}, [updatePos]);
const handleAdd = useCallback(() => setCount(prev => prev + 1), []);
return (
<div className="App">
<div className="block-wrapper">
<div className="top-section" ref={topRef}>
<button type="button" onClick={() => alert(count)}>Show count</button>
<button type="button" onClick={() => setCount(0)}>Reset count</button>
</div>
{[...Array(6)].map((_, i) => (
<Item key={i} onAdd={handleAdd} />
))}
</div>
</div>
);
}
Editor is loading...
Leave a Comment