下面是最小 demo ,逻辑很简单:count 随着鼠标滚轮滚动,不断增加++,通过{divs}渲染出 count 。
const useWheel = (count:number, setCount)=>{
let refDiv = useRef<HTMLDivElement>(null);
useEffect(()=>{
let el = refDiv.current;
let callback = (ev:WheelEvent)=>{
ev.preventDefault();
setCount(count+Math.floor(Math.abs(ev.deltaY/5)));
};
el.addEventListener("wheel", callback, {passive:false});
return (()=>{el.removeEventListener('wheel', callback);});
}, [count]);
return refDiv;
}
export const Main = (props)=>{
let [count, setCount] = useState<number>(0);
let wheel = useWheel(count, setCount);
let divs = (new Array<number>(25000)).fill(0).map((v,i)=>(<div key={i+count}>{i+count}</div>));
return (<div ref={wheel}>
{divs}
</div> );
}
但实际上,渲染的 count 会有「忽增忽减」的现象,感觉不正常。而如果把 25000 条改为 50 条,渲染帧率提高,就不会有同样的问题了。
上面的例子里,useEffect 是依赖 count 的,按我的理解,count 更新会触发 useEffect 调用。而 useEffect 里面用到的 count 就是最新的值,那为什么结果会「忽增忽减」呢?
修改 setCount 为函数形式,好像就解决这个问题了。
setCount((pre)=>pre+Math.floor(Math.abs(ev.deltaY/5)));
但我不理解这里的逻辑:为什么改之前的会有问题呢?难道 useEffect 用的不是最新的 count 吗?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.