Как обновить список, когда новый элемент отправляется с помощью ловушки useState? - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть форма ввода, которая добавляет элементы со связями на график. После добавления элементов в график пользователи могут щелкнуть по ним по отдельности, чтобы просмотреть информацию об их отношениях в другом компоненте.

Я пытаюсь отфильтровать массив, содержащий всю информацию об элементах, для элементов, на которые влияет ассоциация по представлению нового товара. Прямо сейчас это выдает ошибку Cannot read property 'push' of undefined.

Желаемый результат:

  1. Добавить первый элемент
  2. Щелкните первый элемент на графике, чтобы показать подробности элемента
  3. Добавьте второй элемент, свяжите его с первым элементом
  4. В списке «Связи элементов» в деталях элемента (открытых на шаге 2) теперь должна отображаться ассоциация, созданная на шаге 3

Рабочий код (здесь песочница)

Родительский компонент: mainContainer

import React, { useState } from "react";
import ItemForm from "./form";
import ItemGraph from "./graph";
import ItemDetails from "./details";

function MainContainer() {
  const [allItems, setAllItems] = useState([]);
  const [activeItem, setActiveItem] = useState([]);

  return (
    <React.Fragment>
      {/* {console.log(allItems)} */}
      {/* {console.log(activeItem)} */}
      <div id="form" className="mb-5">
        <ItemForm allItems={allItems} setAllItems={setAllItems} />
      </div>
      <div id="graph">
        <ItemGraph
          allItems={allItems}
          activeItem={activeItem}
          setActiveItem={setActiveItem}
        />
      </div>
      <div id="details">
        <ItemDetails activeItem={activeItem} />
      </div>
    </React.Fragment>
  );
}

export default MainContainer;

Дочерний компонент: форма

import React from "react";
import { useForm } from "react-hook-form";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";

function ItemForm(props) {
  const { register, handleSubmit } = useForm();

  const items = props.allItems;
  const options = items.map((item, index) => (
    <option key={index} value={item.itemname}>
      {item.itemname}
    </option>
  ));

  function updateAllItems(newItem, items) {
    items.push(newItem);
    if (items.length > 0) {
      let itemToUpdate = items.filter(item =>
        newItem.associations.includes(item.itemname)
      );
      itemToUpdate.associations.push(newItem);
    }
  }

  const onSubmit = data => {
    updateAllItems(data, props.allItems);
    document.getElementById("item-entry-form").reset();
  };

  return (
    <Form id="item-entry-form" onSubmit={handleSubmit(onSubmit)}>
      <Form.Group controlId="" className="mx-2">
        <Form.Label>Name</Form.Label>
        <Form.Control
          name="itemname"
          type="text"
          placeholder="Enter Item Name"
          ref={register}
        />
        <Form.Label>Description</Form.Label>
        <Form.Control
          name="itemdesc"
          type="text"
          placeholder="Enter Item Description"
          ref={register}
        />
        <Form.Label>Associated To</Form.Label>
        <Form.Control
          as="select"
          multiple
          name="associations"
          defaultValue={["DEFAULT"]}
          ref={register}
        >
          <option value="DEFAULT" disabled>
            Select Items
          </option>
          {options}
        </Form.Control>
      </Form.Group>
      <Button variant="primary" type="submit" className="mb-2">
        Submit
      </Button>
    </Form>
  );
}

export default ItemForm;

Дочерний компонент : graph

import React from "react";

function ItemGraph(props) {
  const graphContainer = {
    height: "250px",
    width: "640px",
    border: "1px solid black",
    marginBottom: "10px",
    marginTop: "10px"
  };
  const itemStyle = {
    display: "inline-block",
    height: "50px",
    width: "50px",
    backgroundColor: "yellow",
    border: "1px solid black"
  };

  const handleClick = item => {
    props.setActiveItem(item);
  };

  const items = props.allItems;
  const options = items.map((item, index) => (
    <div
      key={index}
      value={item.itemname}
      style={itemStyle}
      onClick={() => handleClick(item)}
    >
      {item.itemname}
    </div>
  ));

  return (
    <React.Fragment>
      <div style={graphContainer}>{options}</div>
    </React.Fragment>
  );
}

export default ItemGraph;

Дочерний компонент: подробности

import React from "react";

function ItemDetails(props) {
  const item = props.activeItem;
  let options = "Nothing Yet";
  if (item.associations !== undefined) {
    options = item.associations.map((item, index) => (
      <li key={index} value={item}>
        {item}
      </li>
    ));
  }

  const borderStyle = {
    border: "1px solid black",
    borderCollapse: "collapse",
    padding: "0",
    margin: "0"
  };

  return (
    <React.Fragment>
      <div style={borderStyle}>
        <p style={borderStyle}>Item: {item.itemname}</p>
        <p style={borderStyle}>Item Description: {item.itemdesc}</p>
        <p style={borderStyle}>
          Item Associations:
          {options}
        </p>
      </div>
    </React.Fragment>
  );
}

export default ItemDetails;

Есть идеи, как это исправить или сделать лучше?

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