我制作了一个易于切换的组件,在这里我以一扇门为例。您单击门并打开,如果再次单击它,它将关闭。如果你点击门外,它也会关闭。
我的问题是,在handleClick()
方法中,state.active
总是false
,无论如何。即使我设置了状态,它在我console.log
时返回false。实际的door
确实会分配给"active"
类,那么为什么该方法看不到更改呢?
export default class Door extends React.Component {
constructor() {
super()
this.state = {
active: false,
}
this.close = this.close.bind(this)
this.open = this.open.bind(this)
}
handleClick() {
if (this.state.active == false) {
this.open()
} else {
this.close()
}
}
open() {
document.body.addEventListener('click', this.close, true)
this.setState({active: true})
}
close() {
document.body.removeEventListener('click', this.close, true)
this.setState({active: false})
}
render() {
let classes = {
active: this.state.active ? 'active ' : '',
}
return (
<div onClick={this.handleClick.bind(this)} className={"door " + classes.active}>
</div>
)
}
}
答案 0 :(得分:3)
你应该停止传播:
handleClick(e) {
e.stopPropagation();
if (this.state.active == false) {
this.open()
} else {
this.close()
}
}
当您尝试关闭门时,会调用handleClick两次。一旦通过div点击,然后通过身体点击。这可以通过在处理一次时阻止事件冒泡来避免。
答案 1 :(得分:0)
我认为您的混淆来自于尝试在handleClick
中记录状态,在handleClick
调用this.close()
时,活动状态永远不会成立,始终< / em>发生在您的&#34;外部点击&#34;您在this.open
中设置的事件处理程序。
用户点击门
2a上。 active为false,请调用open()
2B。使用下一次单击
用户点击任意位置
3A。在close()
3B。如果用户点击了门,GOTO 2,否则返回默认状态
通过代理setState
方法,您可以看到活动状态实际上设置为true。
class Door extends React.Component {
constructor(props) {
super(props)
this.state = {
active: false,
}
this.open = this.open.bind(this);
this.close = this.close.bind(this);
}
setState(state) {
console.log("Setting state: ", state);
super.setState(state);
}
handleClick() {
if (this.state.active == false) {
this.open()
} else {
this.close()
}
}
open() {
this.setState({ active: true });
document.body.addEventListener('click', this.close, true)
}
close(event) {
this.setState({active: false});
document.body.removeEventListener('click', this.close, true)
}
render() {
let classes = {
active: this.state.active ? 'active ' : '',
}
return (
<div onClick={this.handleClick.bind(this)} className={"door " + classes.active}>
</div>
)
}
}
ReactDOM.render(<Door />, document.querySelector('#app'));
&#13;
.door {
height: 300px;
width: 100px;
background-color: brown;
}
.active {
background-color: black;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
答案 2 :(得分:0)
我相信发生的事情是它打开,将状态设置为true,然后当你点击门关闭时,domEvent触发,触发close将状态设置为false,然后再次打开。
将您当前拥有的div放在另一个div中,并将该事件添加到div外部。
open() {
var el = document.getElementById('outsideDiv');
el.addEventListener('click', this.close, false)
this.setState({active: true})
}
close() {
var el = document.getElementById('outsideDiv');
el.removeEventListener('click', this.close, false)
this.setState({active: false})
}
render() {
let classes = {
active: this.state.active ? 'active ' : '',
}
return (
<div id="outsideDiv">
<div onClick={this.handleClick.bind(this)} className={"door " + classes.active}>
</div>
</div>
)
}
这样,当您点击门时,它不会记录点击。