Устранение проблем с выпадающими кнопками в панели навигации в реагирующей - PullRequest
1 голос
/ 26 июня 2019

Мне удалось заставить кнопки активировать выпадающие меню, которые исчезают при нажатии кнопки, но проблема в том, что при нажатии любой кнопки появляются все выпадающие списки. Кажется, что когда я пытаюсь установить состояние одной кнопки, она устанавливает состояние всех кнопок. Я хочу, чтобы состояние каждой кнопки имело переменную displayMenu, которая имеет значение true или false. Когда кнопка нажата, она должна изменить свое состояние displayMenu на true и false при нажатии. Что я тут не так делаю?

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import './NavBar.css'; 
import './Body.css'
class NavBar extends Component {
  state = {
    displayMenu: false 
  }

  showDM = () => {
    const displayMenu = true;
    this.setState({ displayMenu }, () => {
      document.addEventListener('click', this.hideDM);
      //document.getElementById("ddc").classList.toggle('show');
    });
  }

  hideDM = (ev) => {
    this.setState({ displayMenu: false }, () => {
      document.removeEventListener('click', this.hideDM)
      //document.getElementsByClassName("dropdown-content").classList.remove('show');

    });
  }

  render() {
    return (
      <header>
        <div className="navbar">
          <div className="dropdown">
            <button onClick={this.showDM} className="dropbtn">About 
              <i className="fa fa-caret-down"></i>
            </button>
            { this.state.displayMenu ? ( 
            <div className="dropdown-content" id="ddc">
              <a href="#mission"><Link to="/mission">Mission</Link></a>
              <a href="#history"><Link to="/history">History</Link></a>
              <a href="#alumni"><Link to="/alumni">Alumni</Link></a>
            </div>
            ):
            ( 
              null 
            )
            }
          </div>
          <div className="dropdown">
            <button onClick={this.showDM} className="dropbtn">Academics 
              <i className="fa fa-caret-down"></i>
            </button>
            { this.state.displayMenu ? (
            <div className="dropdown-content" id="ddc">


              <a href="#curriculum"><Link to="/curriculum">Our Curriculum</Link></a>
              <a href="#study-abroad"><Link to="/study-abroad">Study Abroad</Link></a>
            </div>
            ):
            ( 
              null 
            )
            }
          </div> 

}
export default NavBar;

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Вы можете отправлять различные типы для каждой кнопки в вашу функцию и изменять состояние этой кнопки.

<button onClick={this.showDM("About")} className="dropbtn">About 
    <i className="fa fa-caret-down"></i>
</button>

и функция showDM

showDM = (type) => {
const displayMenu = true;
this.setState({ displayMenu: type });}

и для вашего выпадающего контента вы можете проверить состояние, если оно соответствует его собственному типу

{ this.state.displayMenu === "About" ? ( 
   <div className="dropdown-content" id="ddc">
     <a href="#mission"><Link to="/mission">Mission</Link></a>
     <a href="#history"><Link to="/history">History</Link></a>
     <a href="#alumni"><Link to="/alumni">Alumni</Link></a>
   </div>
   ):
   ( 
     null 
    )}

и ваша функция hideDM может быть такой:

hideDM = (ev) => {
this.setState({ displayMenu: ""});}
0 голосов
/ 26 июня 2019

Вы проверяете одно и то же значение для нескольких кнопок: this.state.displayMenu.Я бы предложил добавить другое значение в ваше состояние и проверить его, например, displayWhich или что-то еще, а затем установить его в зависимости от того, какая кнопка была нажата.При этом вы также можете удалить функцию, чтобы снова скрыть меню:

Я немного изменил структуру, надеюсь, комментарии достаточно описывают, в противном случае, не стесняйтесь спрашивать!

class NavBar extends Component {
  //added constructor for state and binding. you don't need to, but i like it better this way 
  constructor(){
    super();
    this.state =  {
      displayMenu: false, 
      displayWhich: -1
    }
    this.MenuClick = this.MenuClick.bind(this);
  }


  MenuClick(e) => {
    // i use a dom-attribute here, you could also use refs or something different. this is for breviety 
    let target = e.currentTarget.attr("data-which");
    //we assume that if the target is the same as displayWhich, displayMenu is also  true
    // but you could check for that too
    //also a soft check because dom returns string, but i wanted to use ints for the state
   // could also parse the target-value before and then do a hard check

    if(target == this.state.displayWhich){
       this.setState({
       displayMenu: false,
       displayWhich: -1
      })
    }else{
       this.setState({
       displayMenu: true,
       displayWhich:target
      })
    }        

  }



  render() {
    return (
      <header>
        <div className="navbar">
          <div className="dropdown">
            <button onClick={this.menuClick} className="dropbtn" data-which="1">About 
              <i className="fa fa-caret-down"></i>
            </button>
            { ((this.state.displayMenu) && (this.state.displayWhich==1))&&
             ( 
            <div className="dropdown-content" id="ddc">
              <a href="#mission"><Link to="/mission">Mission</Link></a>
              <a href="#history"><Link to="/history">History</Link></a>
              <a href="#alumni"><Link to="/alumni">Alumni</Link></a>
            </div>
            )}
          </div>
          <div className="dropdown">
            <button onClick={this.showDM} className="dropbtn">Academics 
              <i className="fa fa-caret-down"></i>
            </button>
            // CHANGED THIS HERE: 
            // content only displays when condition true, no need to return null
            // notice (condition) && (content)
            {  ((this.state.displayMenu) && (this.state.displayWhich==2)) &&
            (

            <div className="dropdown-content" id="ddc">


              <a href="#curriculum"><Link to="/curriculum">Our Curriculum</Link></a>
              <a href="#study-abroad"><Link to="/study-abroad">Study Abroad</Link></a>
            </div>
            )

            }
          </div> 

}
export default NavBar;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...