组件代码
const DesignerDragScaleCOntainer=()=>{ const { setScale, setRatio } = useAppStore(); const scaleCallback = useCallback( (dsData: DragScaleData) => { console.log("缩放率回调:" + JSON.stringify(dsData.scale)); setScale(dsData.scale); setRatio(dsData.ratio); }, [setScale, setRatio] ); useDragScaleProvider({ container: containRef, content: contentRef, scaleCallback: scaleCallback, }); }
hooks 相关
export interface DragScaleData { scale: number; ratio: number; position: IPoint; } interface DragScaleParams{ container:MutableRefObject<HTMLDivElement> | undefined content:MutableRefObject<HTMLDivElement> | undefined scaleCallback?: (dsData: DragScaleData) => void; } export function useDragScaleProvider(params: DragScaleParams) { const { container, scaleCallback } = params; const { scale, ratio, compute } = useScaleCore(); const [wheelEvent,setWheelEvent] = useState<WheelEvent>() const [position, setPosition] = useState<IPoint>({ x: 0, y: 0 }); const handleWheel = useCallback((e: WheelEvent): void => { if (e.altKey && e.buttons !== 2) { compute(e.deltaY > 0 ? 0 : 1); // setWheelEvent(e) } }, [compute]); useEffect(() => { const handleWheelWithCallback = (e: WheelEvent) => { handleWheel(e); }; const currentCOntainer= container.current; if (currentContainer) { currentContainer.addEventListener('wheel', handleWheelWithCallback, { passive: true }); return () => { currentContainer.removeEventListener('wheel', handleWheelWithCallback); }; } }, [container, handleWheel, scale, ratio, position, scaleCallback]); useEffect(()=>{ scaleCallback?.({ scale, ratio, position }); },[position, ratio, scale, scaleCallback]) return { scale, ratio }; } function useScaleCore(initialMax = 3, initialMin = 0.05, initialScale = 1, initialRatio = 1) { const [max, setMax] = useState(initialMax); const [min, setMin] = useState(initialMin); const [scale, setScale] = useState(initialScale); const [ratio, setRatio] = useState(initialRatio); const compute = useCallback((type: number) => { let _ratio = 1.2; // 缩小 if (type === 0) _ratio = 1 / 1.2; // 限制缩放倍数 let _scale = scale * _ratio; if (_scale > max) { _ratio = max / scale; _scale = max; } else if (_scale < min) { _ratio = min / scale; _scale = min; } // 使用函数式更新方式更新 scale 和 ratio setScale(_scale); setRatio(_ratio); }, [max, min, scale]); return { max, min, scale, ratio, compute }; } export default useScaleCore;
1 tsutomu 2024-06-18 13:44:13 +08:00 加个节流就差不多了,又不是不能用。感觉 hooks 没啥规范,很多流行库用起来也很别扭 |
2 ZGame OP @tsutomu 就是感觉很别扭 useEffect(()=>{ scaleCallback?.({ scale, ratio, position }); },[position, ratio, scale, scaleCallback]) 就是比如这个 我希望回调里把改变的参数传出去,但是 scale 本身是个 state 对象, 你改了他不会立即改变 然后就监测发生变化的时候才传出... |
3 Marthemis 2024-06-19 09:46:20 +08:00 ![]() 试试看这样会不会更舒服点呢 ```js function useScaleCore(initialMax = 3, initialMin = 0.05, initialScale = 1, initialRatio = 1,options){ // 省略... const compute = useCallback((type: number) => { //省略... options?.onScaleChange(_scale) }) } function useDragScaleProvider(){ const { container, scaleCallback } = params; const { scale, ratio, compute } = useScaleCore(3,0.05,1,1,{ onScaleChange:scaleCallback }); // 省略... // 删除这个 effect useEffect(()=>{ scaleCallback?.({ scale, ratio, position }); },[position, ratio, scale, scaleCallback]) } ``` |