Как настроить функцию onClick в меню в Reactjs?

Извините, если это глупый/очевидный вопрос, я новичок в Javascript/React. Я пытаюсь создать меню, заполненное объектами JSON, которые я получаю от вызова API. Поскольку данные JSON представляют собой набор вложенных объектов (я говорю о сотнях объектов), я понял, как рекурсивно вызывать объекты и отображать их в неупорядоченном списке. Кажется, я не могу понять, как добавить функцию onClick, которая при нажатии будет показывать следующий уровень во вложенных объектах.

Я предоставлю несколько скриншотов, чтобы дать вам представление о том, что у меня есть и чего я пытаюсь достичь. Часть рекурсии сбивает меня с толку, как я могу заставить это работать. У кого-нибудь есть идеи?

class Menu extends React.Component {
  state = {
    categories: []
  };

  makeMenuLayer = layer => {
    const layerKeys = Object.entries(layer).map(([key, value]) => (
      <ul>
        {key}
        {this.makeMenuLayer(value)}
      </ul>
    ));
    return <div>{layerKeys}</div>;
  };

  componentDidMount() {
    axios.get("https://www.ifixit.com/api/2.0/categories").then(response => {
      this.setState({ categories: response.data });
    });
  }

  render() {
    const { categories } = this.state;
    return <div>{this.makeMenuLayer(categories)}</div>;
  }
}

это то, что в настоящее время отображается с этим кодом. Я пытаюсь сделать так, чтобы отображался только первый слой объектов, а затем при нажатии на каждый элемент отображался следующий уровень. Например, если я нажимаю «Одежда», отображаются «Аксессуары», «Одежда», «Очки» и т. д., а если я нажимаю «Аксессуары», отображаются галстук и зонт.

Как настроить функцию onClick в меню в Reactjs?

вот скриншот данных, с которыми я работаю, отображаемых в консоли Как настроить функцию onClick в меню в Reactjs?

Поведение ключевого слова "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) для оценки ваших знаний,...
4
0
818
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это можно сделать несколькими способами, однако общая идея состоит в том, чтобы отслеживать дополнительное состояние, чтобы определить, какой слой в иерархии меню в данный момент виден, а какой нет.

Быстрый и достаточно простой способ сделать это — добавить дополнительную карту под названием hidden к состоянию ваших компонентов, которая будет отслеживать видимость слоев меню в вашем дереве меню.

Что-то вроде этого может сработать для вас:

class Menu extends React.Component {
    state = {
    categories: [],
    /* Add extra state to track which layers are visible or not */
    hidden: {}
    };

    /* Define a local helper function that toggles the layer by key */
    toggleMenuLayer = (key) => {

        /* A state change is required to cause a re-render of the menu */
        this.setState(state => {

            const { hidden } = state
            const isHidden = hidden[ key ];

            /* Add or update hidden state for key in hidden map */
            return { hidden : { ...hidden, key : !isHidden }}
        });
    }

    /* Define a local helper function that determines if a layer is visible by its key */
    isLayerToggled = (key) => {

        /* If "not" hidden then layer is visible, or "toggled" */
        return !this.state.hidden[ key ]
    }

    makeMenuLayer = (parentKey, layer) => {
        const layerKeys = Object.entries(layer).map(([key, value]) => {

            /* Compose a unique key for this item based on it's position in the hierarchy */
            const itemKey = `${parentKey}.${key}`;

            return (
                <ul>
                { /* Add a toggle button for this layer */ }
                <button onClick = {() => this.toggleMenuLayer(itemKey)}>{key}</button>

                { /* If layer is toggled then display it's contents */ }
                { this.isLayerToggled(itemKey) && this.makeMenuLayer(value) }
                </ul>
            )
        });
        return <div>{layerKeys}</div>;
    };

    componentDidMount() {
        axios.get("https://www.ifixit.com/api/2.0/categories").then(response => {
            this.setState({ categories: response.data });
        });
    }

    render() {
        const { categories } = this.state;
        return <div>{this.makeMenuLayer(categories)}</div>;
    }
}

Надеюсь, комментарии в коде помогут!

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

Вероятно, не самый эффективный, но я просто подумал об использовании состояния для скрытия/отображения вложенных объектов.

Попробуй это

import React from 'react'

class Menu extends React.Component {
  state = {
    categories: [],
    objectKeys: null,
    tempKeys: []
  }

  makeMenuLayer = layer => {
    const { objectKeys } = this.state
    const layerKeys = Object.entries(layer).map(([key, value]) => (
      <ul key = {key}>
        <div onClick = {() => this.handleShowMore(key)}>{key}</div>
        {objectKeys[key] && this.makeMenuLayer(value)}
      </ul>
    ))
    return <div>{layerKeys}</div>
  }

  handleShowMore = key => {
    this.setState(prevState => ({
      objectKeys: {
        ...prevState.objectKeys,
        [key]: !this.state.objectKeys[key]
      }
    }))
  }

  initializeTempKeys = layer => {
    Object.entries(layer).map(([key, value]) => {
        const newTempKeys = this.state.tempKeys
        newTempKeys.push(key)
        this.setState({ tempKeys: newTempKeys })
        this.initializeTempKeys(value)
      }
    )
  }

  initializeObjectKeys = () => {
    const { tempKeys } = this.state
    let tempObject = {}

    tempKeys.forEach(tempKey => {
      tempObject[tempKey] = true
    })

    this.setState({ objectKeys: tempObject })
  }

  async componentDidMount () {
    const res = await fetch('https://www.ifixit.com/api/2.0/categories')
    const categories = await res.json()
    this.initializeTempKeys(categories)
    this.initializeObjectKeys()
    this.setState({ categories })
  }

  render () {
    const { categories } = this.state
    return <div>{this.makeMenuLayer(categories)}</div>
  }
}

export default Menu

Эй, Райан, еще раз спасибо за вашу помощь. Мне было интересно, не могли бы вы помочь мне с этим. Я хочу добавить стрелки рядом с каждым элементом, под которым находится еще один слой (по сути, если у этого элемента есть дочерние элементы, отобразите стрелку, чтобы указать это). Ты знаешь, я бы сделал это здесь?

Emily 11.05.2019 05:56

Вы можете добавить чекер для value. Если это не пустой массив, верните какой-нибудь значок. Что-то вроде {value.length > 0 && <div>arrow</div>}

Ryan Abis 13.05.2019 16:58

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