使用州

时间:2018-06-15 02:28:46

标签: javascript reactjs

我正在尝试创建一个触发菜单打开的按钮。我最初的想法是在按钮点击上设置状态,但是发生的事情是第一次点击对状态或类没有影响。第二次和随后的点击会触发更改。

我理解为什么可见性的状态不起作用(因为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>
    )
  }
}

3 个答案:

答案 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 您首先检查状态是真还是假,然后才更改状态。 如果它是反向的那么它会起作用。

setStateasynchronous并且在设置状态后有一个回调函数作为其第二个参数。

您可以使用以下代码

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();
  }