使用useState挂钩提交新项目时,如何更新列表?

时间:2020-04-22 20:36:27

标签: javascript reactjs react-hooks

我有一个输入表单,可以将具有关系的项目添加到图形中。将项目添加到图表后,用户可以单独单击它们以查看其在不同组件中的关系信息。

我正在尝试过滤一个数组,该数组包含有关在提交新项目时受到关联影响的项目的所有项目信息。现在,这会引发错误Cannot read property 'push' of undefined

所需的输出:

  1. 添加第一项
  2. 单击图形中的第一项以显示项目详细信息
  3. 添加第二项,并将其关联到第一项
  4. 项目详细信息(在步骤2中打开)中的“项目关联”列表现在应显示在步骤3中创建的关联。

Working Code (Sandbox here)

父组件: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;

子组件:图形

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;

关于如何解决或改进它的任何想法?

0 个答案:

没有答案