簡體   English   中英

為什么React Hook中的useState無法更新狀態

[英]Why useState in React Hook not update state

當我從React Hook嘗試示例時,我遇到有關useState的問題。

在下面的代碼中,當單擊按鈕時,我為document添加事件並檢查count值。 我的期望是在console.log獲得count並以相同的方式查看。 但是實際上,我在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確定是否捕獲。

請注意,在useEffect我傳遞了[capture] ,因此更改時將調用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> 

@基思我理解你的例子,但是當我申請時會感到困惑。 handleClick ,我始終將函數稱為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM