反应状态没有更新
Posted
技术标签:
【中文标题】反应状态没有更新【英文标题】:React state does not get updated 【发布时间】:2020-05-19 18:31:56 【问题描述】:我知道已经有很多关于这个话题的问题被问到了,但感觉每个问题都不同,我找不到与我的问题足够接近的问题。
我有一个带有可拖动ItemComponent
s 的网格。选择后,会显示其他操作图标 (ItemActionIcon
)。单击其中一个操作后,我非常希望取消选择组件(并有效地隐藏操作图标)。
所以在第 77 行 <div onClick=() => this.setState(selected: false) key=index>
我正在尝试将 selected
的状态更新为 false。在文件中提到的所有其他情况下,它已经可以正常工作了。但在这种情况下不是。当我单击该图标时,我可以使用调试器(或尝试使用 console.log)看到 onClick
操作按预期触发,ItemComponent
甚至再次调用 render
方法,但this.state.selected
仍设置为true
。
import React, Component from "react";
import Draggable, DraggableBounds from "react-draggable";
import ItemComponentAction from "./ItemComponentAction";
import ItemActionIcon from "./ItemActionIcon";
export interface Position
x: number;
y: number;
export interface ItemComponentProps
gridSquareSize: number;
canvasBounds: DraggableBounds;
margin: number;
position: Position;
interface ItemComponentState
gridSquareSize: number;
canvasBounds: DraggableBounds;
margin: number;
selected: boolean;
export default abstract class ItemComponent extends Component<ItemComponentProps>
protected abstract readonly icon: string;
protected abstract readonly actions: ItemComponentAction[];
state: ItemComponentState;
protected constructor(props: ItemComponentProps)
super(props);
this.state =
gridSquareSize: props.gridSquareSize,
canvasBounds: props.canvasBounds,
margin: props.margin,
selected: false
;
render()
return (
<Draggable grid=[this.state.gridSquareSize / 2, this.state.gridSquareSize / 2]
defaultPosition=
x: this.state.margin + this.props.position.x * this.state.gridSquareSize,
y: this.state.margin + this.props.position.y * this.state.gridSquareSize
handle=".handle"
bounds=this.state.canvasBounds
onDrag=() => this.setState(selected: false)
>
<div tabIndex=0
className="handle"
onClick=() => this.setState(selected: true)
onBlur=() => this.setState(selected: false)
style=
position: 'absolute',
backgroundColor: 'red',
width: this.state.gridSquareSize,
height: this.state.gridSquareSize,
cursor: "move"
>
this.icon
!this.state.selected || !this.actions.length
? null
: (
<div style=
position: 'absolute',
bottom: "0"
>
this.actions.map((action, index) => (
<div onClick=() => this.setState(selected: false) key=index>
<ItemActionIcon ...action/>
</div>
))
</div>
)
</div>
</Draggable>
);
那么有什么关系呢?
【问题讨论】:
似乎您在父 div 中有一个 onclick 处理程序,将selected
设置为 false
?如果点击内层div,外层div的onclick函数不也会运行吗...?
不...实际上不是...父母的 onClick 没有被触发...但无论如何我都会提取整个内容。也许这会触发这件事
你做了什么来验证父onClick是否被触发?
我不确定我是否可以信任调试器(编译 TS 后断点通常会出现在错误的位置),所以我只是添加了 console.log()
很可能 onClick 实际上被触发了,而您只是没有看到它或没有明显地记录它。为了进一步验证这一点,您可以尝试将代码与问题中的示例相同,并在内部 div onClick 事件上执行 event.stopPropagation()
。
【参考方案1】:
组件的外部<div>
有自己的onClick
处理程序,它将您的状态值设置回false
。尝试在内部 onClick
处理的事件上使用 stopPropagation()
。这将阻止事件传播到外部父级<div>
,并且只有内部onClick
处理程序在被单击时才会执行。
!this.state.selected || !this.actions.length ? null : (
<div
style=
position: "absolute",
bottom: "0"
>
this.actions.map((action, index) => (
<div
onClick=e =>
e.stopPropagation();
this.setState( selected: false );
key=index
>
<ItemActionIcon ...action />
</div>
))
</div>
);
【讨论】:
以上是关于反应状态没有更新的主要内容,如果未能解决你的问题,请参考以下文章
使用 componentDidUpdate 在反应中更新状态