V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ZGame
V2EX  ›  React

我在参考开源项目改写一段监听滚轮,更改编辑器缩放的 hooks,虽然实现了我的功能,但是这个 hooks 写的我感觉怪怪的,请教下大佬其中的问题

  •  
  •   ZGame · 8 天前 · 703 次点击

    组件代码

    
    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;
      
    
    
    3 条回复    2024-06-19 09:46:20 +08:00
    tsutomu
        1
    tsutomu  
       8 天前
    加个节流就差不多了,又不是不能用。感觉 hooks 没啥规范,很多流行库用起来也很别扭
    ZGame
        2
    ZGame  
    OP
       8 天前
    @tsutomu 就是感觉很别扭
    useEffect(()=>{
    scaleCallback?.({ scale, ratio, position });
    },[position, ratio, scale, scaleCallback])
    就是比如这个 我希望回调里把改变的参数传出去,但是 scale 本身是个 state 对象, 你改了他不会立即改变 然后就监测发生变化的时候才传出...
    Marthemis
        3
    Marthemis  
       7 天前   ❤️ 1
    试试看这样会不会更舒服点呢

    ```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])

    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   993 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:12 · PVG 04:12 · LAX 13:12 · JFK 16:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.