Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用挂钩拖放React_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 使用挂钩拖放React

Javascript 使用挂钩拖放React,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我主要是一个后端工程师,一直在尝试实现,但失败了,一个简单的拖放滑块我在反应 首先,我将向您展示不使用debounce的行为: 以下是debounce的行为: 我稍微修改了一下,从中取出的去盎司 我想我有两个问题,一个是快速闪烁,去抖动应该解决,另一个是不正确的左,我不知道如何修复。出于某种原因,onDrag,rect.left也将父对象(100+10)的所有左边距添加到它。这发生在Chrome和Safari上 我的问题是,我如何使这个拖放工作?我做错了什么?我的代码如下: import

我主要是一个后端工程师,一直在尝试实现,但失败了,一个简单的拖放滑块我在反应

首先,我将向您展示不使用debounce的行为:

以下是debounce的行为:

我稍微修改了一下,从中取出的去盎司

我想我有两个问题,一个是快速闪烁,去抖动应该解决,另一个是不正确的
,我不知道如何修复。出于某种原因,onDrag,rect.left也将父对象(100+10)的所有左边距添加到它。这发生在Chrome和Safari上

我的问题是,我如何使这个拖放工作?我做错了什么?我的代码如下:

 import React, {
   Dispatch,
   MouseEvent,
   RefObject,
   SetStateAction,
   useEffect,
   useRef,
   useState
 } from "react";

 const useDebounce = (callback: any, delay: number) => {
   const latestCallback = useRef(callback);
   const latestTimeout = useRef(1);

   useEffect(() => {
     latestCallback.current = callback;
   }, [callback]);

   return (obj: any) => {
     const { event, args } = obj;
     event.persist();
     if (latestTimeout.current) {
       clearTimeout(latestTimeout.current);
     }

     latestTimeout.current = window.setTimeout(
       () => latestCallback.current(event, ...args),
       delay
     );
   };
 };

 const setPosition = (
   event: any,
   setter: any
 ) => {
     const rect = event.target.getBoundingClientRect();
     const clientX: number = event.pageX;
     console.log('clientX: ', clientX)
     // console.log(rect.left)
     setter(clientX - rect.left)
 };

 const Slider: React.FC = () => {
   const [x, setX] = useState(null);
   const handleOnDrag = useDebounce(setPosition, 100)

   return (
     <div style={{ position: "absolute", margin: '10px' }}>
       <div
         style={{ position: "absolute", left: "0", top: "0" }}
         onDragOver={e => e.preventDefault()}
       >
         <svg width="300" height="10">
           <rect
             y="5"
             width="300"
             height="2"
             rx="10"
             ry="10"
             style={{ fill: "rgb(96,125,139)" }}
           />
         </svg>
       </div>
       <div
         draggable={true}
         onDrag={event => handleOnDrag({event, args: [setX]})}
         // onDrag={event => setPosition(event, setX)}
         style={{
           position: "absolute",
           left: (x || 0).toString() + "px",
           top: "5px",
           width: "10px",
           height: "10px",
           padding: "0px",
         }}
       >
         <svg width="10" height="10" style={{display:"block"}}>
           <circle cx="5" cy="5" r="4" />
         </svg>
       </div>
     </div>
   );
 };
import-React{
派遣,
MouseEvent,
重新设定目标,
采取行动,
使用效果,
useRef,
使用状态
}从“反应”;
const useDebounce=(回调:any,延迟:number)=>{
const latestCallback=useRef(回调);
const latestTimeout=useRef(1);
useffect(()=>{
latestCallback.current=回调;
},[callback]);
返回(对象:任何)=>{
const{event,args}=obj;
event.persist();
if(最晚超时。当前){
clearTimeout(latestTimeout.current);
}
latestTimeout.current=window.setTimeout(
()=>latestCallback.current(事件,…参数),
延迟
);
};
};
常数设置位置=(
事件:任何,
塞特:有吗
) => {
const rect=event.target.getBoundingClientRect();
const clientX:number=event.pageX;
log('clientX:',clientX)
//console.log(rect.left)
setter(clientX-rect.left)
};
常量滑块:React.FC=()=>{
const[x,setX]=useState(null);
常数handleOnDrag=useDebounce(设置位置,100)
返回(
e、 preventDefault()}
>
handleOnDrag({event,args:[setX]})}
//onDrag={event=>setPosition(event,setX)}
风格={{
位置:“绝对”,
左:(x | | 0).toString()+“px”,
顶部:“5px”,
宽度:“10px”,
高度:“10px”,
填充:“0px”,
}}
>
);
};

谢谢。

拖拉和翁德拉也有自己的不幸。用简单的鼠标事件尝试我的手

您可以在下面的沙箱中找到一个工作代码


其来源如下

import React, { useRef, useState, useEffect, useCallback } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const isDragging = useRef(false);
  const dragHeadRef = useRef();
  const [position, setPosition] = useState(0);

  const onMouseDown = useCallback(e => {
    if (dragHeadRef.current && dragHeadRef.current.contains(e.target)) {
      isDragging.current = true;
    }
  }, []);

  const onMouseUp = useCallback(() => {
    if (isDragging.current) {
      isDragging.current = false;
    }
  }, []);

  const onMouseMove = useCallback(e => {
    if (isDragging.current) {
      setPosition(position => position + e.movementX);
    }
  }, []);

  useEffect(() => {
    document.addEventListener("mouseup", onMouseUp);
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mousemove", onMouseMove);
    return () => {
      document.removeEventListener("mouseup", onMouseUp);
      document.removeEventListener("mousedown", onMouseDown);
      document.removeEventListener("mousemove", onMouseMove);
    };
  }, [onMouseMove, onMouseDown, onMouseUp]);

  return (
    <div
      style={{
        flex: "1",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        height: "100vh"
      }}
    >
      <div
        style={{
          height: "5px",
          width: "500px",
          background: "black",
          position: "absolute"
        }}
      >
        <div
          ref={dragHeadRef}
          style={{
            left: `${position}px`,
            transition: 'left 0.1s ease-out',
            top: "-12.5px",
            position: "relative",
            height: "30px",
            width: "30px",
            background: "black",
            borderRadius: "50%"
          }}
        />
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React,{useRef,useState,useffect,useCallback}来自“React”;
从“react dom”导入react dom;
导入“/styles.css”;
函数App(){
const isDragging=useRef(false);
const dragHeadRef=useRef();
const[position,setPosition]=useState(0);
const onMouseDown=useCallback(e=>{
if(dragHeadRef.current&&dragHeadRef.current.contains(e.target)){
IsDraging.current=真;
}
}, []);
const onMouseUp=useCallback(()=>{
if(IsDraging.current){
IsDraging.current=假;
}
}, []);
const onMouseMove=useCallback(e=>{
if(IsDraging.current){
设置位置(位置=>position+e.movementX);
}
}, []);
useffect(()=>{
文件。添加了监听器(“mouseup”,onMouseUp);
文件。添加了文本列表(“鼠标向下”,onMouseDown);
document.addEventListener(“mousemove”,onMouseMove);
return()=>{
文件。删除EventListener(“mouseup”,onMouseUp);
文档。删除EventListener(“mousedown”,onMouseDown);
document.removeEventListener(“mousemove”,onMouseMove);
};
},[onMouseMove,onMouseDown,onmousedup]);
返回(
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);

逻辑的关键是
e.movementX
,它返回自上次事件发生以来鼠标沿x轴移动的距离量。用它来设置dragHeader的左侧位置

通过使用
范围
类型的
输入
,您可以简化您的生活。单击此处查看示例滑块:(包括一个工作代码沙盒示例)@MattCarlotta这可能会让我的生活更轻松。谢谢。非常感谢@johnny peter,不过我想知道,如果输入列表为空,为什么要使用useCallback,即依赖项为空,并且每次都会运行,换句话说,为什么不使用普通函数?这只是一个小的性能优化。如果它是一个普通函数,那么在每次渲染时都会创建一个新函数,这将触发不必要地调用useEffect。