为什么在 React Hook 中使用状态不更新状态



当我尝试从 React Hook 中获取示例时,我遇到了有关useState的问题。

在下面的代码中,单击按钮时,我为document添加事件并检查count的值。我的期望是count console.log并查看相同的内容。但实际上,我在console中获得了旧值(初始化值(,并在视图中获得了新值。我不明白为什么count在视图中更改而count在事件的回调中没有更改。

还有一件事,当我使用setCount(10);(固定一个数字(时。并多次单击按钮(>2(,然后单击外部,我只从checkCount那里获得了2个日志。是 React 手表count不改变,然后下次不要addEventListener

import React, { useState } from "react";
function Example() {
  const [count, setCount] = useState(0);
  const add = () => {
    setCount(count + 1);
    console.log("value set is ", count);
    document.addEventListener("click", checkCount);
  };
  const checkCount = () => {
    console.log(count);
  };
  return (
    <div>
      <p>You clicked {count} times</p>
      <p>Click button first then click outside button and see console</p>
      <button onClick={() => add()}>Click me</button>
    </div>
  );
}
export default Example;
如果要使用

document.addEventListener 捕获组件外部的事件,则需要使用 useEffect 挂钩添加事件,然后可以使用useState来确定是否捕获。

请注意,在我传递[capture] useEffect中,这将使 useEffect 在更改时被调用,对此捕获布尔值的简单检查确定我们是否添加事件。

通过使用useEffect,我们还避免了任何内存泄漏,这也应对了卸载组件时,它也知道删除事件。

const {useState, useEffect} = React;
function Test() {
  const [capture, setCapture] = useState(false);
  const [clickInfo, setClickInfo] = useState("Not yet");
  
  function outsideClick() {
    setClickInfo(Date.now().toString());
  }
  
  useEffect(() => {
    if (capture) {
      document.addEventListener("click", outsideClick);
      return () => {
        document.removeEventListener("click", outsideClick);
      }
    }
  }, [capture]);
  
  return <div>
    <p>
    Click start capture, then click anywhere, and then click stop capture, and click anywhere.</p>
    <p>{capture ? "Capturing" : "Not capturing"}</p>
    <p>Clicked outside: {clickInfo}</p>
    <button onClick={() => setCapture(true)}>
      Start Capture
     </button>
    <button onClick={() => setCapture(false)}>
      Stop Capture
    </button>
  </div>
}
ReactDOM.render(<React.Fragment>
  <Test/>
</React.Fragment>, document.querySelector('#mount'));
p { user-select: none }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="mount"></div>

@Keith我

理解你的例子,但是当我申请时会感到困惑。在起源上,我总是调用函数是handleClick,并且在运行handleClickOutside后仍然调用它,但现在我不知道如何使用钩子应用它。

这是我想要的代码而不是钩子

class ClickOutSide extends Component {
  constructor(props) {
    super(props)
    this.wrapperRef = React.createRef();
    this.state = {
      active: false
    }
  }
  handleClick = () => {
    if(!this.state.active) {
      document.addEventListener("click", this.handleClickOut);
      document.addEventListener("contextmenu", this.handleClickOut);
      this.props.clickInside();
    } else {
      document.removeEventListener("click", this.handleClickOut);
      document.removeEventListener("contextmenu", this.handleClickOut);
    }
    this.setState(prevState => ({
      active: !prevState.active,
   }));
  };
  handleClickOut = event => {
    const { target } = event;
    if (!this.wrapperRef.current.contains(target)) {
      this.props.clickOutside();
    }
    this.handleClick()
  }
  render(){
    return (
      <div
        onDoubleClick={this.props.onDoubleClick}
        onContextMenu={this.handleClick}
        onClick={this.handleClick}
        ref={this.wrapperRef}
      >
        {this.props.children}
      </div>
    )
  }
}
export default ClickOutSide

相关内容

  • 没有找到相关文章