У меня есть форма ввода, которая добавляет элементы со связями на график. После добавления элементов в график пользователи могут щелкнуть по ним по отдельности, чтобы просмотреть информацию об их отношениях в другом компоненте.
Я пытаюсь отфильтровать массив, содержащий всю информацию об элементах, для элементов, на которые влияет ассоциация по представлению нового товара. Прямо сейчас это выдает ошибку Cannot read property 'push' of undefined
.
Желаемый результат:
- Добавить первый элемент
- Щелкните первый элемент на графике, чтобы показать подробности элемента
- Добавьте второй элемент, свяжите его с первым элементом
- В списке «Связи элементов» в деталях элемента (открытых на шаге 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;
Есть идеи, как это исправить или сделать лучше?