Goal: Create a new product component through onClick
of a button where it would display a modal
containing textfields
to be filled up with the new product's name and price. We then pass the value of those textfields to the data.jsx
(data source for rendering the product components) after clicking the Add button
inside the modal in order to create a new instance of data info of the new product.
Problem: I am having trouble on passing the values of the textfields from the modal going to data.jsx
since I literally have no clue how to properly pass those values into a plain database file. I think props, hooks, etc. might not work on passing the values.
Modal appearance (after clicking Add New Product button
):
Modal appearance (with textfield values):
Modal source code (ModalAddProduct.jsx):
import React from "react";
import { Typography } from "@mui/material";
import {
BrowserRouter as Router,
Routes,
Route,
useNavigate
} from "react-router-dom";
import { TextField } from "@mui/material";
import { useState } from "react";
import "./ModalStyleAddProduct.css";
function ModalAddProduct({ setOpenModalAddProduct }) {
const navigate = useNavigate();
const [itemName, setItemName] = useState("");
const [itemPrice, setItemPrice] = useState("");
const navigateToDraftsPage = () => {
navigate("/draftspage");
};
return (
<div className="modalBackground3">
<div className="modalContainer3">
<div className="titleCloseBtn3">
<button
onClick={() => {
setOpenModalAddProduct(false);
}}
>
<Typography sx={{ color: "white" }}>X</Typography>
</button>
</div>
<div className="title">
<h1 className="modalTitleUp">Add New Item Product</h1>
</div>
<div className="body">
<TextField
onChange={(g1) => setItemName(g1.target.value)}
className="inputRounded"
placeholder="Item Name"
variant="outlined"
size="small"
/>
<TextField
onChange={(g2) => setItemPrice(g2.target.value)}
className="inputRounded"
placeholder="Item Price"
variant="outlined"
size="small"
sx={{ width: 100 }}
/>
</div>
<div className="footer">
<button
onClick={() => {
setOpenModalAddProduct(false);
}}
id="noBtn3"
>
Cancel
</button>
<button>Add</button>
</div>
</div>
</div>
);
}
export default ModalAddProduct;
Database source code (data.jsx):
const data = {
products: [
{
id: "1",
name: "MacBook",
price: 1400,
image: "https://picsum.photos/id/180/2400/1600"
},
{
id: "2",
name: "Old Car",
price: 2400,
image: "https://picsum.photos/id/111/4400/2656"
},
{
id: "3",
name: "W Shoes",
price: 1000,
image: "https://picsum.photos/id/21/3008/2008"
}
]
};
export default data;
Full functioning app in CodeSandbox:
App inspired and based from YT: https://www.youtube.com/watch?v=AmIdY1Eb8tY
It would indeed help a lot to gather tips and guides on how to handle data passing when it comes to plain database files which only contains a const array of objects
.
Thank you very much!
CodePudding user response:
All right... I think the best would be to use useContext or Redux, but you can also pass the props back to the parent (Main.js) from ModalAddProduct.
Where you have your "Add" button:
<button onClick={sendDataToParent}>Add</button>
now add sendDataToParent function in this file.
const sendDataToParent = () => {
props.sendData(itemName, itemPrice);
};
We are passing all the information we want back to the parent. We could also pass it as an object.
Now back in our main.js file:
const [updatedProductsList, addProd] = useState(products);
And we will use updatedProductsList in our map function at the bottom. On the first render, it will display your 3 products you have.
And last but not least... Remember the sendData we send (props.sendData)? Let's update our updatedProductsList that we declared using the useState hook.
const sendData = (name, price) => {
addProd([...updatedProductList, { name, price }]);
};
Let's "listen" for sendData from the child. As soon as it is triggered the sendData in the parent will be triggered.
<ModalAddProduct
sendData={sendData}
setOpenModalAddProduct={setModalOpenAddProduct}
/>
Now you need to add an image field for consistency. Ideally, as mentioned before redux could be a good tool to use so you could pass your dummy data there and update them as you go along. Please note if you try to add the new item to the cart it will show an error. It is because the price on your form is a string, not a number. BTW, there is a concept called props drilling in react, hence why redux or useContext are preferable. I hope this is all clear :)