Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.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 AddEventListener不';看不见范围_Javascript_Event Handling_React Hooks_Onclicklistener - Fatal编程技术网

Javascript AddEventListener不';看不见范围

Javascript AddEventListener不';看不见范围,javascript,event-handling,react-hooks,onclicklistener,Javascript,Event Handling,React Hooks,Onclicklistener,当我使用OnClick设置处理程序时,它工作正常,console.log始终使用实际状态。但是当我使用AddEventListener时,它只工作一次,然后使用旧状态 行为以外的原因是什么 请参阅链接 p.S使用[count]作为useffect依赖项来修复它,但每次它都只是创建新的侦听器,不要认为这样做的正确方法存在闭包问题 事实上,在每次渲染中,您的组件将创建一个新函数showCount,该函数修复了该计数 例如: 在第一次渲染中,创建一个函数showCount,该函数固定为count=1

当我使用OnClick设置处理程序时,它工作正常,console.log始终使用实际状态。但是当我使用AddEventListener时,它只工作一次,然后使用旧状态

行为以外的原因是什么

请参阅链接


p.S使用[count]作为useffect依赖项来修复它,但每次它都只是创建新的侦听器,不要认为这样做的正确方法存在闭包问题

事实上,在每次渲染中,您的组件将创建一个新函数showCount,该函数修复了该计数

例如:

在第一次渲染中,创建一个函数showCount,该函数固定为count=1

在第二次渲染中,创建一个函数showCount,该函数固定为count=2

在3渲染中,创建一个函数showCount,并将其固定为count=3

问题是,当您的计数发生这样的变化时,您没有更改showcount

useEffect(() => {
    let buttonShow = document.querySelector(".buttonShow");
    buttonShow.addEventListener("click", showCount, true);
    return () => {
      buttonShow.removeEventListener("click", showCount, true);
    };
  }, [count]); 
您可以看到日志计数2,因为使用增量时,计数的引用不会更改

我认为最好的解决方案是使用组件类:

import React from "react";

    class CounterAddEvent extends React.PureComponent {
      state = {
        count: 1
      };
      componentDidMount() {
        let buttonShow = document.querySelector(".buttonShow");
        buttonShow.addEventListener("click", this.showCount, true);
      }
      componentWillUnmount() {
        let buttonShow = document.querySelector(".buttonShow");
        buttonShow.removeEventListener("click", this.showCount, true);
      }
      increaseCount = () => {
        this.setState({ count: this.state.count + 1 });
      };
      showCount = () => {
        console.log(this.state.count);
      };
      render() {
        return (
          <div>
            <button onClick={this.increaseCount} className="input">
              increase
            </button>
            <button>{this.state.count}</button>
            <button className="buttonShow">Show console</button>
          </div>
        );
      }
    }
    export default CounterAddEvent;
从“React”导入React;
类CounterAddEvent扩展了React.PureComponent{
状态={
计数:1
};
componentDidMount(){
let buttonShow=document.querySelector(“.buttonShow”);
buttonShow.addEventListener(“单击”,this.showCount,true);
}
组件将卸载(){
let buttonShow=document.querySelector(“.buttonShow”);
buttonShow.removeEventListener(“单击”,this.showCount,true);
}
递增计数=()=>{
this.setState({count:this.state.count+1});
};
showCount=()=>{
console.log(this.state.count);
};
render(){
返回(
增加
{this.state.count}
显示控制台
);
}
}
导出默认反加法器;

您有一个关闭问题

事实上,在每次渲染中,您的组件将创建一个新函数showCount,该函数修复了该计数

例如:

在第一次渲染中,创建一个函数showCount,该函数固定为count=1

在第二次渲染中,创建一个函数showCount,该函数固定为count=2

在3渲染中,创建一个函数showCount,并将其固定为count=3

问题是,当您的计数发生这样的变化时,您没有更改showcount

useEffect(() => {
    let buttonShow = document.querySelector(".buttonShow");
    buttonShow.addEventListener("click", showCount, true);
    return () => {
      buttonShow.removeEventListener("click", showCount, true);
    };
  }, [count]); 
您可以看到日志计数2,因为使用增量时,计数的引用不会更改

我认为最好的解决方案是使用组件类:

import React from "react";

    class CounterAddEvent extends React.PureComponent {
      state = {
        count: 1
      };
      componentDidMount() {
        let buttonShow = document.querySelector(".buttonShow");
        buttonShow.addEventListener("click", this.showCount, true);
      }
      componentWillUnmount() {
        let buttonShow = document.querySelector(".buttonShow");
        buttonShow.removeEventListener("click", this.showCount, true);
      }
      increaseCount = () => {
        this.setState({ count: this.state.count + 1 });
      };
      showCount = () => {
        console.log(this.state.count);
      };
      render() {
        return (
          <div>
            <button onClick={this.increaseCount} className="input">
              increase
            </button>
            <button>{this.state.count}</button>
            <button className="buttonShow">Show console</button>
          </div>
        );
      }
    }
    export default CounterAddEvent;
从“React”导入React;
类CounterAddEvent扩展了React.PureComponent{
状态={
计数:1
};
componentDidMount(){
let buttonShow=document.querySelector(“.buttonShow”);
buttonShow.addEventListener(“单击”,this.showCount,true);
}
组件将卸载(){
let buttonShow=document.querySelector(“.buttonShow”);
buttonShow.removeEventListener(“单击”,this.showCount,true);
}
递增计数=()=>{
this.setState({count:this.state.count+1});
};
showCount=()=>{
console.log(this.state.count);
};
render(){
返回(
增加
{this.state.count}
显示控制台
);
}
}
导出默认反加法器;
错误来自设置“useState(1)”,这将始终在实现“++计数”之前将值“计数”重新初始化为1

所以我使用的简单技巧是将useState(1)重构为useState(x)。。 因此,x可以从当前计数值更新

下面是重构后的代码

错误来自设置“useState(1)”,这将始终在实现“++计数”之前将值“计数”重新初始化为1

所以我使用的简单技巧是将useState(1)重构为useState(x)。。 因此,x可以从当前计数值更新

下面是重构后的代码


谢谢你的回复。我在这里看到了闭包,但是为什么函数showCount没有看到count的实际状态。在这里可以看到,闭包可以看到实际值。为什么对我来说不起作用?因为引用没有改变。正是因为这个原因,在你的问题中,你可以看到计数2的日志,我想我几乎明白了你的意思。在这种情况下,每个渲染的计数都不相同,而是新的一个??因为这不是我看到的唯一解释,为什么它没有看到回复的变化。我在这里看到了闭包,但是为什么函数showCount没有看到count的实际状态。在这里可以看到,闭包可以看到实际值。为什么对我来说不起作用?因为引用没有改变。正是因为这个原因,在你的问题中,你可以看到计数2的日志,我想我几乎明白了你的意思。在这种情况下,每个渲染的计数都不相同,而是新的一个??因为除了我看到的唯一解释,为什么它没有看到变化谢谢你解决问题的方法。它可能打破了纯函数规则。不管怎样,这真的很有趣!伟大的顺便说一下,这并不是因为您重新初始化了状态,而是从外部变量中获取计数。事实上,根据文档,“初始值将仅在初始渲染时指定”。这段代码的工作原理是一样的:谢谢你的解决方法。它可能打破了纯函数规则。不管怎样,这真的很有趣!伟大的顺便说一下,这并不是因为您重新初始化了状态,而是从外部变量中获取计数。事实上,根据文档,“初始值将仅在初始渲染时指定”。此代码的工作方式相同: