Ref.current 在组件挂载时未定义,当我需要它时它不会导致重新渲染
Ref.current is undefined when component mount and it can not cause a re render when I need it
我想做一个可拖动的 div 所以我创建了一个 ref 来访问 div 所以我可以在 Rxjs fromEvent 运算符中使用它
问题是 ref 对象在 fromEvent 中使用后会被设置(第一次 ref 还没有设置)所以我把它放在一个 if 语句中所以它只在设置时使用 ref。
现在 dragRef.current 已设置,但组件不再执行
这是我使用的代码:
import React, { useRef, useEffect, useState } from "react";
import "./App.css";
import { fromEvent } from "rxjs";
import { map } from "rxjs/operators";
const App: React.FC = () => {
const dragRef = useRef<HTMLDivElement>(null);
const mouseMove = fromEvent(document, "mousedown");
if (dragRef.current != undefined) {
debugger;
const mouseDown = fromEvent(dragRef.current, "mousedown");
const mouseUp = fromEvent(dragRef.current, "mouseup");
const mouseDrag = mouseDown.pipe(
map((evt: MouseEvent | Event) => {
// let offsetX = evt.clientX - dragRef.current.offsetLeft;
// let offsetY = evt.clientY - dragRef.current.offsetTop;
console.log(evt);
return evt;
})
);
mouseDrag.subscribe(v => console.log(v));
}
return (
<div className="App">
<header className="App-header">
<div className="drag" ref={dragRef}></div>
</header>
</div>
);
};
export default App;
您可以使用 useEffect hook,它将您要观察的变量数组作为依赖项。
因此,在您的情况下,当您的 ref 更改时,您将执行该功能。
像
useEffect(() => {
if (dragRef.current != undefined) {
debugger;
const mouseDown = fromEvent(dragRef.current, "mousedown");
const mouseUp = fromEvent(dragRef.current, "mouseup");
const mouseDrag = mouseDown.pipe(
map((evt: MouseEvent | Event) => {
// let offsetX = evt.clientX - dragRef.current.offsetLeft;
// let offsetY = evt.clientY - dragRef.current.offsetTop;
console.log(evt);
return evt;
})
);
mouseDrag.subscribe(v => console.log(v));
}
}, [dragRef])
这是最终代码,它完美地适用于 React
中的可拖动 div
import React, { useRef, useEffect, useState } from "react";
import "./App.css";
import { fromEvent } from "rxjs";
import { map, takeUntil, mergeMap } from "rxjs/operators";
const App: React.FC = () => {
const dragRef = useRef<HTMLDivElement>(null);
const [position, setPosition] = useState({top: 100, left: 100})
useEffect(() => {
if (dragRef != null) {
const mouseMove = fromEvent(document, "mousemove");
//@ts-ignore
const mouseDown = fromEvent(dragRef.current, "mousedown");
//@ts-ignore
const mouseUp = fromEvent(dragRef.current, "mouseup");
const mouseDrag = mouseDown.pipe(
mergeMap((evt: any) => {
//@ts-ignore
let offsetX = evt.clientX - dragRef!.current.offsetLeft;
//@ts-ignore
let offsetY = evt.clientY - dragRef!.current.offsetTop;
return mouseMove.pipe(
map((e: any) => ({
top: e.clientY - offsetY,
left: e.clientX - offsetX
})),
takeUntil(mouseUp),
);
})
);
mouseDrag.subscribe((value: any) => {
console.log(value)
setPosition(value)
});
}
}, [dragRef]);
return (
<div className="App">
<header className="App-header">
<div className="drag" ref={dragRef} style={{top: position.top +'px', left: position.left +'px'}}></div>
</header>
</div>
);
};
export default App;
我想做一个可拖动的 div 所以我创建了一个 ref 来访问 div 所以我可以在 Rxjs fromEvent 运算符中使用它
问题是 ref 对象在 fromEvent 中使用后会被设置(第一次 ref 还没有设置)所以我把它放在一个 if 语句中所以它只在设置时使用 ref。
现在 dragRef.current 已设置,但组件不再执行
这是我使用的代码:
import React, { useRef, useEffect, useState } from "react";
import "./App.css";
import { fromEvent } from "rxjs";
import { map } from "rxjs/operators";
const App: React.FC = () => {
const dragRef = useRef<HTMLDivElement>(null);
const mouseMove = fromEvent(document, "mousedown");
if (dragRef.current != undefined) {
debugger;
const mouseDown = fromEvent(dragRef.current, "mousedown");
const mouseUp = fromEvent(dragRef.current, "mouseup");
const mouseDrag = mouseDown.pipe(
map((evt: MouseEvent | Event) => {
// let offsetX = evt.clientX - dragRef.current.offsetLeft;
// let offsetY = evt.clientY - dragRef.current.offsetTop;
console.log(evt);
return evt;
})
);
mouseDrag.subscribe(v => console.log(v));
}
return (
<div className="App">
<header className="App-header">
<div className="drag" ref={dragRef}></div>
</header>
</div>
);
};
export default App;
您可以使用 useEffect hook,它将您要观察的变量数组作为依赖项。 因此,在您的情况下,当您的 ref 更改时,您将执行该功能。 像
useEffect(() => {
if (dragRef.current != undefined) {
debugger;
const mouseDown = fromEvent(dragRef.current, "mousedown");
const mouseUp = fromEvent(dragRef.current, "mouseup");
const mouseDrag = mouseDown.pipe(
map((evt: MouseEvent | Event) => {
// let offsetX = evt.clientX - dragRef.current.offsetLeft;
// let offsetY = evt.clientY - dragRef.current.offsetTop;
console.log(evt);
return evt;
})
);
mouseDrag.subscribe(v => console.log(v));
}
}, [dragRef])
这是最终代码,它完美地适用于 React
中的可拖动 divimport React, { useRef, useEffect, useState } from "react";
import "./App.css";
import { fromEvent } from "rxjs";
import { map, takeUntil, mergeMap } from "rxjs/operators";
const App: React.FC = () => {
const dragRef = useRef<HTMLDivElement>(null);
const [position, setPosition] = useState({top: 100, left: 100})
useEffect(() => {
if (dragRef != null) {
const mouseMove = fromEvent(document, "mousemove");
//@ts-ignore
const mouseDown = fromEvent(dragRef.current, "mousedown");
//@ts-ignore
const mouseUp = fromEvent(dragRef.current, "mouseup");
const mouseDrag = mouseDown.pipe(
mergeMap((evt: any) => {
//@ts-ignore
let offsetX = evt.clientX - dragRef!.current.offsetLeft;
//@ts-ignore
let offsetY = evt.clientY - dragRef!.current.offsetTop;
return mouseMove.pipe(
map((e: any) => ({
top: e.clientY - offsetY,
left: e.clientX - offsetX
})),
takeUntil(mouseUp),
);
})
);
mouseDrag.subscribe((value: any) => {
console.log(value)
setPosition(value)
});
}
}, [dragRef]);
return (
<div className="App">
<header className="App-header">
<div className="drag" ref={dragRef} style={{top: position.top +'px', left: position.left +'px'}}></div>
</header>
</div>
);
};
export default App;