[英]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.