Меню React Mapping из JSON

У меня есть элементы меню с прокруткой, и заголовки каждого элемента жестко закодированы в константу вместе с идентификатором.

const list = [
  { name: "category1", id: 0 },
  { name: "category2", id: 1 },
  { name: "category3", id: 2 },
  { name: "category4", id: 3 },
  { name: "category5", id: 4 },
  { name: "category6", id: 5 },
  { name: "category7", id: 6 },
  { name: "category8", id: 7 }
];

У меня есть файл json, который содержит имя категории для каждого ребенка:

    {
  "results": [
    {
      "category": "category1",
      "name": {
        "title": "mr",
        "first": "ernesto",
        "last": "roman"
      },
      "email": "[email protected]",
      "id": {
        "name": "DNI",
        "value": "73164596-W"
      },
      "picture": {
        "large": "https://randomuser.me/api/portraits/men/73.jpg",
        "medium": "https://randomuser.me/api/portraits/med/men/73.jpg",
        "thumbnail": "https://randomuser.me/api/portraits/thumb/men/73.jpg"
      }
    },
    {
      "category": "category2",
      "name": {
        "title": "mr",
        "first": "adalbert",
        "last": "bausch"
      },
      "email": "[email protected]",
      "id": {
        "name": "",
        "value": null
      } etc....

Я хочу показать эти категории "category": "category1", как заголовки моего меню, теперь мне нужно начать без сохранения состояния и добавить их из JSON, часть выборки из JSON выполняется локально в componentDidMount, но я не уверен, как я могу сопоставьте их с именами меню, чтобы сделать меню динамичным, я в основном хочу такой же вывод, но из json, не жестко запрограммированного. вот фрагмент песочницы, буду признателен за помощь.

https://codesandbox.io/s/2prw4j729p?fontsize=14&moduleview=1

Поведение ключевого слова "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
4 692
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Просто преобразуйте вывод JSON в объект, например list, с функцией map из результатов, а затем установите как MenuItems в состоянии, которое вы передаете функции в render(). Как это.

import React, { Component } from "react";
import ScrollMenu from "react-horizontal-scrolling-menu";
import "./menu.css";

// One item component
// selected prop will be passed
const MenuItem = ({ text, selected }) => {
  return (
    <div>
      <div className = "menu-item">{text}</div>
    </div>
  );
};

// All items component
// Important! add unique key
export const Menu = list =>
  list.map(el => {
    const { name, id } = el;
    return <MenuItem text = {name} key = {id} />;
  });

const Arrow = ({ text, className }) => {
  return <div className = {className}>{text}</div>;
};

export class Menucat extends Component {
  state = {
    selected: "0",
    MenuItems: []
  };

  componentDidMount() {
    fetch("menu.json")
      .then(res => res.json())
      .then(result => {
        const items = result.results.map((el, idx) => {
          return { name: el.category, id: idx };
         });
        this.setState({
          isLoaded: true,
          MenuItems: items
        });
      });
  }

  render() {
    const { selected, MenuItems } = this.state;
    // Create menu from items
    const menu = Menu(MenuItems, selected);

    return (
      <div className = "App">
        <ScrollMenu
          data = {menu}
          selected = {selected}
          onSelect = {this.onSelect}
          alignCenter = {true}
          tabindex = "0"
        />
      </div>
    );
  }
}

export default Menucat;

Ваше здоровье!

что, если в menu.json также есть подкатегория?

Praveen Rana 06.09.2019 08:44

Похоже, вам вообще не нужно жестко кодировать список категорий. В вашем componentDidMount() извлеките json и сгруппируйте результаты в отдельные категории следующим образом:

const json = {
    "results": [
        {
            category: "category1",
            name: "Fred"
        },
        {
            category: "category1",
            name: "Teddy"
        },
        {
            category: "category2",
            name: "Gilbert"
        },
        {
            category: "category3",
            name: "Foxy"
        },
    ]
}
const grouped = json.results.reduce((acc, cur) => {
    if (!acc.hasOwnProperty(cur.category)) {
        acc[cur.category] = []
    }
    acc[cur.category].push(cur)
    return acc;
}, { })

// parent object now has 3 properties, namely category1, category2 and category3
console.info(JSON.stringify(grouped, null, 4))

// each of these properties is an array of bjects of same category
console.info(JSON.stringify(grouped.category1, null, 4))
console.info(JSON.stringify(grouped.category2, null, 4))
console.info(JSON.stringify(grouped.category3, null, 4))

Обратите внимание, что этот json имеет 4 объекта в массиве результатов, 2 объекта категории 1 и 1 объекта категории 2 и категории 3. Вы можете запустить этот код в отдельном файле, чтобы увидеть, как он работает. Конечно, вы будете получать объект json с сервера. Я просто поставил его для демонстрации.

Затем установите состояние: this.setState({ grouped })

Затем в render() вы показываете только категории, в которых есть такие элементы, как:

const menuBarButtons = Object.keys(this.state.grouped).map((category) => {
    /* your jsx here */
    return <MenuItem text = {category} key = {category} onClick = {this.onClick} blah = {blah}/>
    /* or something , it's up to you */
})

Я предполагаю, что вы показываете элементы на основе текущей выбранной категории this.state.selected. Итак, после того, как вы визуализировали свое меню, вы должны сделать что-то вроде:

const selectedCatItems = this.state.grouped[this.state.selected].map((item) => {
    return <YourItem name = {item.name} key = {item.id} blah = {blah} />
})

Затем сделайте это:

return (
    <div className = "app">
        <MenuBar blah = {blah}>
            {menuBarButtons}
        </Menubar>
        <div for your item showing area>
            {selectedCatItems}
        </div>
    </div>
)

Кроме того, не забудьте изменить свой onClick(), чтобы он правильно устанавливал состояние this.state.selected. Я верю, что вы можете понять это сами.

Надеюсь, поможет.

PS: я не писал полное решение для копирования/вставки для вашей проблемы просто потому, что я не хочу читать и понимать детали вашего пользовательского интерфейса и весь компонент для передачи данных компонента.

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