Нажмите, чтобы открыть всех братьев и сестер - React

Когда я нажимаю на одну из кнопок меню, братья и сестры открываются. Мне нужно, чтобы каждая из кнопок несла свое независимое содержимое. Сейчас все дети, сгруппированные независимо друг от друга, появляются вместе на отце, который щелкает

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

class Nav extends Component{
    constructor(props){
        super(props)
        this.state = {
            menuSubmenu:[],
            abrirSubmenu: false,
        }
        this.submenuClick = this.submenuClick.bind(this);
    }
    submenuClick() {
        this.setState(state => ({
            abrirSubmenu: !state.abrirSubmenu
          }));
        //alert('Click!')
    }
    componentWillMount(){
        fetch('fake.php')
        .then(response => response.json())
        .then(menuSubmenu =>{

            const PadreMap = menuSubmenu.reduce((acc, obj) => {
                if (!acc[obj.Padre]) {
                  acc[obj.Padre] = {
                    ...obj,
                    Hijo: [obj.Hijo],
                    Description: [obj.Description]
                  };
                } else {
                  !acc[obj.Padre].Hijo.includes(obj.Hijo) && acc[obj.Padre].Hijo.push(obj.Hijo);
                  //!acc[obj.Padre].Hijo.includes(obj.Hijo) && acc[obj.Padre].Hijo.push(obj.Description)
                }
                return acc;
              }, {});

                this.setState({
                        menuSubmenu: Object.keys(PadreMap).map((padre) => ({
                        menu: padre,
                        submenu: PadreMap[padre].Hijo,
                        id: PadreMap.Id,
                        descripcion: PadreMap[padre].Description,
                        url: PadreMap[padre].URL
                }))

            })
            console.info(PadreMap);
        })
    }

    render() {
        if (this.state.menuSubmenu.length > 0) {
          return(
            <nav className = "nav">
                <div className = "menu">
                    <ul className = "list">
                        {this.state.menuSubmenu.map(datos => <Menu key = {datos.id} menu = {datos.menu} submenu = {datos.submenu} descripcion = {datos.descripcion} submenuClick = {this.submenuClick} abrirSubmenu = {this.state.abrirSubmenu}/>)}
                    </ul>
                    <div className = "content-bnt">
                        <button id = "desplegar" className='btn btn--rounded'>
                            <Icon icon = "flecha" className='ico-flecha'/>
                        </button>
                    </div>  
                </div>
            </nav>
          );
        }
        return (<p>Cargando usuarios...</p>);
    }
}

class Menu extends Component{
    render(){
        return (
            <li key = {this.props.id} className = "list__item">
                <button title = {this.props.menu} id = {"mn-" + this.props.menu} className = "desplegable" onClick = {this.props.submenuClick}><Icon icon = "auriculares" className='ico-auriculares'/>{this.props.menu}</button>
            {
            this.props.abrirSubmenu
                ? (
                <div id = "sb-crm" className = "submenu">
                    {this.props.submenu.map(hijo => <h3 className = "nav--title"><Icon icon = "descargar" className='ico-descargar'/>{hijo}</h3>)}
                    <ul className = "list">
                        <li className = "list__item">
                            {this.props.descripcion.map(tercerNivel => <a href = {this.props.url} title = {this.props.descripcion}>{tercerNivel}</a>)}
                        </li>
                    </ul>
                </div>
                )
                : (
                null
                )
            }
            </li>
        )
    }
}

export default Nav;

Еще мне нужно, чтобы нажатием на каждую из кнопок (Padre) скрывалось содержимое других родителей (Padre) и показывалось только ваше. Прямо сейчас это не работает, и содержимое ВСЕХ родителей (Падре) отображается при нажатии любой кнопки.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
182
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У каждого родителя должно быть свое состояние.

const padreState = {};
// crear estado para cada padre
Object.keys(PadreMap).forEach(item => {
  padreState['padre-' + PadreMap[item].Id] = false;
});

this.setState({
  menuSubmenu: Object.keys(PadreMap).map(padre => ({
    menu: padre,
    submenu: PadreMap[padre].Hijo,
    id: PadreMap[padre].Id, // cambiaron desde PadreMap.Id
    descripcion: PadreMap[padre].Description,
    url: PadreMap[padre].URL
  })),
  padreState: padreState
});

подменю по клику

toggle = padreState => {
  Object.keys(padreState).forEach(item => {
    padreState[item] = false;
  });
};

submenuClick(padre) {

  const { padreState } = this.state;
  const corriente = { ...padreState };

  const toggle = !corriente[padre];

  this.toggle(corriente); // toggle menu items
  corriente[padre] = toggle;

  this.setState({
    padreState: corriente
  });
  //alert('Click!')
}

вызовите функцию, например, в вашем <Menu .../>

submenuClick = {() => this.submenuClick('padre-' + datos.id)}
abrirSubmenu = {this.state.padreState['padre-' + datos.id]}

полный код

class Nav extends Component {
  constructor(props) {
    super(props);
    this.state = {
      menuSubmenu: [],
      abrirSubmenu: false,
      padreState: {}
    };
    this.submenuClick = this.submenuClick.bind(this);
  }

  toggle = padreState => {
    Object.keys(padreState).forEach(item => {
      padreState[item] = false;
    });
  };

  submenuClick(padre) {

    const { padreState } = this.state;
    const corriente = { ...padreState };

    const toggle = !corriente[padre];

    this.toggle(corriente);
    corriente[padre] = toggle;

    this.setState({
      padreState: corriente
    });
    //alert('Click!')
  }

  componentWillMount() {
    fetch('fake.php')
      .then(response => response.json())
      .then(menuSubmenu => {
        const PadreMap = menuSubmenu.reduce((acc, obj) => {
          if (!acc[obj.Padre]) {
            acc[obj.Padre] = {
              ...obj,
              Hijo: [obj.Hijo],
              Description: [obj.Description]
            };
          } else {
            !acc[obj.Padre].Hijo.includes(obj.Hijo) &&
              acc[obj.Padre].Hijo.push(obj.Hijo);
            //!acc[obj.Padre].Hijo.includes(obj.Hijo) && acc[obj.Padre].Hijo.push(obj.Description)
          }
          return acc;
        }, {});

        const padreState = {};
        // crear estado para cada padre
        Object.keys(PadreMap).forEach(item => {
          padreState['padre-' + PadreMap[item].Id] = false;
        });

        this.setState({
          menuSubmenu: Object.keys(PadreMap).map(padre => ({
            menu: padre,
            submenu: PadreMap[padre].Hijo,
            id: PadreMap[padre].Id, // cambiaron desde PadreMap.Id
            descripcion: PadreMap[padre].Description,
            url: PadreMap[padre].URL
          })),
          padreState: padreState
        });
        console.info(PadreMap);
      });
  }

  render() {
    if (this.state.menuSubmenu.length > 0) {
      return (
        <nav className = "nav">
          <div className = "menu">
            <ul className = "list">
              {this.state.menuSubmenu.map(datos => (
                <Menu
                  key = {datos.id}
                  menu = {datos.menu}
                  submenu = {datos.submenu}
                  descripcion = {datos.descripcion}
                  submenuClick = {() => this.submenuClick('padre-' + datos.id)}
                  abrirSubmenu = {this.state.padreState['padre-' + datos.id]}
                />
              ))}
            </ul>
            <div className = "content-bnt">
              <button id = "desplegar" className = "btn btn--rounded">
                <Icon icon = "flecha" className = "ico-flecha" />
              </button>
            </div>
          </div>
        </nav>
      );
    }
    return <p>Cargando usuarios...</p>;
  }
}

class Menu extends Component {
  render() {
    return (
      <li key = {this.props.id} className = "list__item">
        <button
          title = {this.props.menu}
          id = {'mn-' + this.props.menu}
          className = "desplegable"
          onClick = {this.props.submenuClick}
        >
          <Icon icon = "auriculares" className = "ico-auriculares" />
          {this.props.menu}
        </button>
        {this.props.abrirSubmenu ? (
          <div id = "sb-crm" className = "submenu">
            {this.props.submenu.map(hijo => (
              <h3 className = "nav--title">
                <Icon icon = "descargar" className = "ico-descargar" />
                {hijo}
              </h3>
            ))}
            <ul className = "list">
              <li className = "list__item">
                {this.props.descripcion.map(tercerNivel => (
                  <a href = {this.props.url} title = {this.props.descripcion}>
                    {tercerNivel}
                  </a>
                ))}
              </li>
            </ul>
          </div>
        ) : null}
      </li>
    );
  }
}

export default Nav;

Другие вопросы по теме