Javascript 如何在功能组件中创建静态功能?
我正在尝试在功能性React组件中添加和删除事件侦听器。监听器可以很好地添加,但在被要求删除时不会被删除。我认为问题在于我引用的函数在每个组件渲染时都会重新创建,因此当removeEventListener尝试删除它时,它与addEventListener添加它时的函数引用不同 我尝试将Javascript 如何在功能组件中创建静态功能?,javascript,html,reactjs,Javascript,Html,Reactjs,我正在尝试在功能性React组件中添加和删除事件侦听器。监听器可以很好地添加,但在被要求删除时不会被删除。我认为问题在于我引用的函数在每个组件渲染时都会重新创建,因此当removeEventListener尝试删除它时,它与addEventListener添加它时的函数引用不同 我尝试将handlemousemove移出组件,但它需要访问组件中生成的setState挂钩 const handleMouseMove = e => { setYOffset(e.clientY-280)
handlemousemove
移出组件,但它需要访问组件中生成的setState挂钩
const handleMouseMove = e => {
setYOffset(e.clientY-280)
setXOffset(e.clientX-350)
}
const followMouse = () => {
if (isFollowingMouse){
setIsFollowingMouse(false)
document.removeEventListener("mousemove", handleMouseMove)
} else {
setIsFollowingMouse(true)
document.addEventListener("mousemove", handleMouseMove)
}
}
...
<button name="mouse" onClick={followMouse}>
Follow Mouse
</button>
const handleMouseMove=e=>{
设置偏移(e.clientY-280)
setXOffset(e.clientX-350)
}
常量followMouse=()=>{
如果(是鼠标){
SetIsFollowing鼠标(错误)
document.removeEventListener(“mousemove”,handleMouseMove)
}否则{
SetIsFollower鼠标(真)
document.addEventListener(“mousemove”,handleMouseMove)
}
}
...
跟随鼠标
所有执行分支都会在此处命中,但document.removeEventListener(“mousemove”,handleMouseMove)
实际上不会删除事件侦听器
在功能组件中有没有一种“静态方法”?这就是问题所在吗
这里有一个完整代码的代码沙盒链接:我认为您对该问题的描述是正确的。一个快速修复方法是在应用程序函数之外定义变量handleMouseMove——本质上是使变量保持静态,而不是每次渲染都重新创建
然后,在函数体中,仅当handleMouseMove变量当前未分配时才分配该变量,并在将IsFollowMouse设置为false时将其设置回null。我认为您对该问题的描述是正确的。一个快速修复方法是在应用程序函数之外定义变量handleMouseMove——本质上是使变量保持静态,而不是每次渲染都重新创建
然后,在函数体中,仅当handleMouseMove变量当前未分配时才分配该变量,并在将IsFollowMouse设置为false时将其设置回null。以前的方法是使用,但现在钩子已经到达
const MyComponent=(道具)=>{
const[IsFollowMouse,SetIsFollowMouse]=React.useState(false);
const[xOffset,setXOffset]=React.useState(0);
const[yOffset,setYOffset]=React.useState(0);
常量handleMouseMove=e=>{
如果(是鼠标){
设置偏移(e.clientY-28);
setXOffset(e.clientX-35);
}
};
常量followMouse=()=>{
setisfollowmouse(!isfollowmouse);
}
常量样式={
“猫”:{
“背景颜色”:“红色”,
“高度”:“20px”,
'位置':'绝对',
“左”:xOffset,
“顶”:yOffset,
“宽度”:“20px”,
'display':是否有鼠标?'block':'none'
}
};
返回(
C
跟随鼠标
)
}
ReactDOM.render(,document.getElementById('root'))代码>
html,
身体,
#根{
身高:100%;
}
旧的方法是使用,但现在钩子已经出现了
const MyComponent=(道具)=>{
const[IsFollowMouse,SetIsFollowMouse]=React.useState(false);
const[xOffset,setXOffset]=React.useState(0);
const[yOffset,setYOffset]=React.useState(0);
常量handleMouseMove=e=>{
如果(是鼠标){
设置偏移(e.clientY-28);
setXOffset(e.clientX-35);
}
};
常量followMouse=()=>{
setisfollowmouse(!isfollowmouse);
}
常量样式={
“猫”:{
“背景颜色”:“红色”,
“高度”:“20px”,
'位置':'绝对',
“左”:xOffset,
“顶”:yOffset,
“宽度”:“20px”,
'display':是否有鼠标?'block':'none'
}
};
返回(
C
跟随鼠标
)
}
ReactDOM.render(,document.getElementById('root'))代码>
html,
身体,
#根{
身高:100%;
}
使用React 16.7,您可以使用挂钩来完成以下操作:
import React, { useCallback, useEffect, useState } from 'react';
const DraggedComponent = React.memo(
props => {
const [isFollowingMouse, setIsFollowingMouse] = useState(false);
const [xOffset, setXOffset] = useState(0);
const [yOffset, setYOffset] = useState(0);
const handleMouseMove = useCallback(
e => {
if (isFollowingMouse) {
setYOffset(e.clientY-28);
setXOffset(e.clientX-35);
}
}, [isFollowingMouse, setYOffset, setXOffset]
);
useEffect(
() => {
document.addEventListener('mousemove', handleMouseMove);
return () => document.removeEventListener('mousemove', handleMouseMove);
},
[handleKeyDown]
);
const followMouse = () => setIsFollowingMouse(!isFollowingMouse);
return (
<div onMouseMove={handleMouseMove}>
<div>C</div>
<button name="mouse" onClick={followMouse}>
Follow Mouse
</button>
</div>
)
}
);
ReactDOM.render(<DraggedComponent />, document.getElementById('root'));
import React,{useCallback,useffect,useState}来自“React”;
常量DraggedComponent=React.memo(
道具=>{
const[IsFollowMouse,SetIsFollowMouse]=useState(false);
const[xOffset,setXOffset]=useState(0);
const[yOffset,setYOffset]=useState(0);
const handleMouseMove=useCallback(
e=>{
如果(是鼠标){
设置偏移(e.clientY-28);
setXOffset(e.clientX-35);
}
},[IsFollowMouse,setYOffset,setXOffset]
);
使用效果(
() => {
文件。添加的列表器(“mousemove”,handleMouseMove);
return()=>document.removeEventListener('mousemove',handleMouseMove);
},
[handleKeyDown]
);
const followMouse=()=>setisfollowmouse(!isfollowmouse);
返回(
C
跟随鼠标
)
}
);
ReactDOM.render(,document.getElementById('root'));
在本例中,React.memo()
确保仅当状态或属性更改时才重新绘制组件。类似的useCallback()
将缓存mousemove事件的事件侦听器,这样,只有在mouse
、setYOffset
或setXOffset
更改之后,而不是每次重新渲染时,才会重新创建此侦听器<创建组件后,以及每次更改handleMouseMove
回调时,都会调用code>useEffect
。此外,它还返回一个函数,即