我正在尝试创建一个触发菜单打开的按钮。我最初的想法是在按钮点击上设置状态,但是发生的事情是第一次点击对状态或类没有影响。第二次和随后的点击会触发更改。
我理解为什么可见性的状态不起作用(因为setState是一个异步方法)但是如何从初始点击中改变它呢?
import React, { Component } from 'react';
export default class Social extends Component {
constructor() {
super();
// class of the div that will change
this.menuVisibility = "social--icons_cntr--close";
// managing the visibility of the menu items
this.state = {
visible: false
};
this.handleMouseDown = this.handleMouseDown.bind(this);
this.toggleMenu = this.toggleMenu.bind(this);
}
handleMouseDown(e) {
// if the state is visible, use the open class
if (this.state.visible === true) {
this.menuVisibility = "social--icons_cntr--open";
}
// if the state is not visible use the close class
else if (this.state.visible === false) {
this.menuVisibility = "social--icons_cntr--close";
}
// call the the toggleMenu method
this.toggleMenu();
e.stopPropagation();
}
toggleMenu() {
this.setState(
{ visible: !this.state.visible })
console.log("visibility: ", this.state.visible);
console.log("menuvis ", this.menuVisibility);
}
render() {
return(
<div className="social--cntr">
<div className={this.menuVisibility}>
<a className="social--icons-link" href="#">[X]</a>
</div>
<div className="social--btn-click social--btn-open"
onMouseDown={this.handleMouseDown}>
<span>+</span>
</div>
</div>
)
}
}
答案 0 :(得分:1)
了解setState
async ,然后应该更改此结构。根据状态将类绑定到条件语句,例如
<div className={{ (this.state.visible ? 'social--icons_cntr--open' : 'social--icons_cntr--close') }}>
然后在onMouseDown
函数中只有this.setState({{ !visible }})
。这样,组件将按照生命周期方法(即ComponentDidUpdate
答案 1 :(得分:1)
setState
有一个回调方法的第二个参数。您可以在那里使用代码,以便更新控制台记录的值。
toggleMenu() {
this.setState(
{ visible: !this.state.visible },
() => {
console.log("visibility: ", this.state.visible);
console.log("menuvis ", this.menuVisibility);
})
}
但是,在这种情况下,你想要更新视图,最好只使用JSX模板中的状态值并以这种方式更新视图。
您可以在模板中使用以下语法:
<div className={this.state.visible ? 'social--icons_cntr--close' : 'social--icons_cntr--open'} >
在此处找到StackBlitz示例:https://stackblitz.com/edit/react-nszfds
答案 2 :(得分:0)
这不是因为setState
是异步的,而是因为次要logical error
您首先检查状态是真还是假,然后才更改状态。
如果它是反向的那么它会起作用。
是setState
是asynchronous
并且在设置状态后有一个回调函数作为其第二个参数。
您可以使用以下代码
handleMouseDown(e) {
this.setState({ visible: !this.state.visible },()=>{
// if the state is visible, use the open class
if (this.state.visible === true) {
this.menuVisibility = "social--icons_cntr--open";
}
// if the state is not visible use the close class
else if (this.state.visible === false) {
this.menuVisibility = "social--icons_cntr--close";
}
})
e.stopPropagation();
}