Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/81.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 如何在功能组件中创建静态功能?_Javascript_Html_Reactjs - Fatal编程技术网

Javascript 如何在功能组件中创建静态功能?

Javascript 如何在功能组件中创建静态功能?,javascript,html,reactjs,Javascript,Html,Reactjs,我正在尝试在功能性React组件中添加和删除事件侦听器。监听器可以很好地添加,但在被要求删除时不会被删除。我认为问题在于我引用的函数在每个组件渲染时都会重新创建,因此当removeEventListener尝试删除它时,它与addEventListener添加它时的函数引用不同 我尝试将handlemousemove移出组件,但它需要访问组件中生成的setState挂钩 const handleMouseMove = e => { setYOffset(e.clientY-280)

我正在尝试在功能性React组件中添加和删除事件侦听器。监听器可以很好地添加,但在被要求删除时不会被删除。我认为问题在于我引用的函数在每个组件渲染时都会重新创建,因此当removeEventListener尝试删除它时,它与addEventListener添加它时的函数引用不同

我尝试将
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
。此外,它还返回一个函数,即