Reactjs 为什么React钩子中的useState不更新状态
当我尝试React Hook中的示例时,我遇到了一个关于Reactjs 为什么React钩子中的useState不更新状态,reactjs,react-hooks,Reactjs,React Hooks,当我尝试React Hook中的示例时,我遇到了一个关于useState的问题 在下面的代码中,当单击按钮时,我为文档添加事件,并检查计数的值。 我的期望是在console.log中获取count,并以相同的方式查看。但实际上,我在控制台中得到了旧值(init值)&视图中的新值。我不明白为什么视图中的count发生了变化,而事件回调中的count没有发生变化 还有一件事,当我使用setCount(10)时(确定一个数字)。多次点击按钮(>2),然后点击外部,我从checkCount中只得到了2条
useState
的问题
在下面的代码中,当单击按钮时,我为文档
添加事件,并检查计数
的值。
我的期望是在console.log
中获取count
,并以相同的方式查看。但实际上,我在控制台中得到了旧值(init值)
&视图中的新值。我不明白为什么视图中的count
发生了变化,而事件回调中的count
没有发生变化
还有一件事,当我使用setCount(10)时代码>(确定一个数字)。多次点击按钮(>2),然后点击外部,我从checkCount
中只得到了2条日志。它是不是反应手表count
不改变,然后下次不addEventListener
import React,{useState}来自“React”;
函数示例(){
const[count,setCount]=useState(0);
常量添加=()=>{
设置计数(计数+1);
日志(“值集为”,计数);
文档。添加的列表器(“单击”,检查计数);
};
常量检查计数=()=>{
控制台日志(计数);
};
返回(
您单击了{count}次
首先单击按钮,然后单击外部按钮并查看控制台
添加()}>单击我
);
}
导出默认示例;
如果要使用document.addEventListener捕获组件外部的事件,则需要使用useffect
钩子添加事件,然后可以使用useState
确定是否捕获
请注意,在我传递的useffect
中,这将使useffect在发生更改时被调用,对该捕获布尔值的简单检查将确定是否添加事件
通过使用useEffect,我们还可以避免任何内存泄漏,这也可以在您卸载组件时处理,它也知道要删除事件
const{useState,useffect}=React;
功能测试(){
const[capture,setCapture]=useState(false);
const[clickInfo,setClickInfo]=useState(“尚未”);
函数outsideClick(){
setClickInfo(Date.now().toString());
}
useffect(()=>{
如果(捕获){
文件。添加的文件列表(“单击”,外部单击);
return()=>{
文档。删除EventListener(“单击”,外部单击);
}
}
},[捕获];
返回
单击开始捕获,然后单击任意位置,然后单击停止捕获,然后单击任意位置
{捕获?“捕获”:“未捕获”}
已在外部单击:{clickInfo}
setCapture(真)}>
开始捕获
setCapture(false)}>
停止捕获
}
ReactDOM.render(
,document.querySelector('mount')代码>
p{用户选择:无}
如果要使用document.addEventListener捕获组件外部的事件,则需要使用useffect
钩子添加事件,然后可以使用useState
确定是否捕获
请注意,在我传递的useffect
中,这将使useffect在发生更改时被调用,对该捕获布尔值的简单检查将确定是否添加事件
通过使用useEffect,我们还可以避免任何内存泄漏,这也可以在您卸载组件时处理,它也知道要删除事件
const{useState,useffect}=React;
功能测试(){
const[capture,setCapture]=useState(false);
const[clickInfo,setClickInfo]=useState(“尚未”);
函数outsideClick(){
setClickInfo(Date.now().toString());
}
useffect(()=>{
如果(捕获){
文件。添加的文件列表(“单击”,外部单击);
return()=>{
文档。删除EventListener(“单击”,外部单击);
}
}
},[捕获];
返回
单击开始捕获,然后单击任意位置,然后单击停止捕获,然后单击任意位置
{捕获?“捕获”:“未捕获”}
已在外部单击:{clickInfo}
setCapture(真)}>
开始捕获
setCapture(false)}>
停止捕获
}
ReactDOM.render(
,document.querySelector('mount')代码>
p{用户选择:无}
@Keith我理解你的例子,但当我应用时会感到困惑。在origin中,我总是调用函数ishandleClick
,并在运行handleClickOutside
后仍然调用它,但现在我不知道如何使用hook应用它
这是我的代码,我想用它代替Hook
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
类ClickOutSide扩展组件{
建造师(道具){
超级(道具)
this.wrapperRef=React.createRef();
此.state={
活动:错误
}
}
handleClick=()=>{
如果(!this.state.active){
document.addEventListener(“单击”,此.handleClickOut);
document.addEventListener(“contextmenu”,this.handleClickOut);
this.props.clickInside();
}否则{
document.removeEventListener(“单击”,此.handleClickOut);
document.removeEventListener(“contextmenu”,this.handleClickOut);
}
this.setState(prevState=>({
活动:!prevState.active,
}));
};
handleClickOut=事件=>{
const{target}=事件;
如果(!this.wrapperRef.current.contains(目标)){
this.props.clickout();
}
这个。handleClick()
}
render(){
返回(
{this.props.children}
)
}
}
导出默认值单击外部
@Keith我理解你的例子,但当我应用时会感到困惑。在origin中,我总是调用函数ishandleClick
,并在运行handleClickOutside
后仍然调用它,但现在我不知道如何使用hook应用它
这是我的代码,我想用它代替Hook
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
类ClickOutSide扩展组件{
建造师(道具){
超级(道具)
this.wrapperRef=React.createRef();