Реагировать: получение реквизита из нескольких массивов с использованием .map - PullRequest
2 голосов
/ 07 августа 2020

Я создаю приложение в стиле ERP, используя MERN и Redux. Мой бэкэнд работает хорошо, я могу добавлять вещи через свой API и все такое, но у меня есть некоторые глупые проблемы с моим интерфейсом.

Идея в том, что у меня есть объекты-элементы и я хочу получить к ним доступ через модальный. Само модальное окно работает, и кнопка, используемая для открытия модального окна, фактически получает имена объектов через l oop.

Проблема возникает внутри ModalBody - он только извлекает информацию из первый объект в таблице. Я пробовал такие методы, как this.props.customer, items.customer, this.items.customer, и многие, многие другие безуспешно.

Было бы здорово, если бы я мог экспортировать компонент как класс, но если он невозможно, это нормально.

Ответы [ 3 ]

4 голосов
/ 07 августа 2020

Вам не нужно создавать модальное окно для каждого элемента. Просто перечислите элементы и создайте одно модальное окно. После этого, когда элемент был нажат, передайте связанный элемент в модальный и установите его как видимый.

Я создаю для вас мини-образец.

import React, { Component } from 'react';
import { render } from 'react-dom';

const Modal = (props) => {
  return (
    props.visible ? (
      <div>
        Product info
        <hr />
        <h3>{props.item.name}</h3>
      </div>
    ) : ""
  )
}

class App extends Component {
  constructor() {
    super();
    this.state = {
      selectedItem: null,
      modalState: false
    };
  }

  data = [{
    id: 1,
    name: "p1"
  }, {
    id: 2,
    name: "p2"
  }, {
    id: 3,
    name: "p3"
  },
  ]

  handleItemClick = (id) => {
    this.setState({
      modalState: true,
      selectedItem: this.data.find(a => a.id === id)
    })
  }

  render() {
    const { modalState, selectedItem } = this.state

    const mappedList = this.data.map(
      (i) => (
        <li key={i.id} onClick={() => this.handleItemClick(i.id)}>{i.name}</li>
      )
    );

    return (
      <div>
        <ul>{mappedList}</ul>
        <Modal visible={modalState} item={selectedItem} />
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

https://stackblitz.com/edit/react-gheoek

3 голосов
/ 07 августа 2020

Я не уверен, что понимаю ваше намерение, но я бы передал массив items компоненту Modal в качестве опоры, а затем использовал карту в компоненте Modal ПОСЛЕ ModalBody. То, как вы делаете сейчас, вы рендерете множество вещей (включая модальные) для каждого элемента в массиве items.

2 голосов
/ 07 августа 2020

Я не уверен, как выглядит ваш массив, но пробовали ли вы использовать map() вот так?

{
  items.map((item, key) =>
    <CSSTransition key={key} timeout={500} classNames="fade">
      <ListGroupItem key={item._id}>
        <Button color="light" style={{ width: "100%" }} onClick={this.toggle}>{item.name}</Button>
        <Modal isOpen={this.state.modal} toggle={this.toggle}>
          <ModalHeader toggle={this.toggle} key={item._id}>{item.name}</ModalHeader>
          <ModalBody key={key}>
            <p>Customer: {item.customer}</p>
            <p>Location: {item.location}</p>
            <p>Dilemma: {item.dilemma}</p>
          </ModalBody>
        </Modal>
      </ListGroupItem>
    </CSSTransition>
  )
}

Также вы хотите отобразить все элементы из массива в одном конкретном c модальное окно или вы хотите заполнить одно модальное окно элементом из массива? В последнем случае было бы лучше визуализировать только одно модальное окно и передать свойства элемента для указанного c элемента модальному.

...