I am getting data from server. I don't know exactly how many items in the api. Therefore, I am using map method in html. Below is the return part.
if (loading) {
return (
<div>
<div>
<Header />
<Sidebar />
</div>
<h1>LOADING ...</h1>
</div>
);
}
if (error) console.log(error);
return (
<div>
<div>
<Header />
<Sidebar />
<h1>Menu Edit Page</h1>
{edit === false ? (
<div>
<table>
<tbody>
{
data?.map((item, index) => (
<tr>
<td>Name: </td>
<td>{item?.name}</td>
{/* Full_Name: { item.name },
User_Email: { item.email } */}
</tr>
))
}
</tbody>
</table>
<Button onClick={() => editMenu()}>edit</Button>
</div>
) : (
<div>
<table>
<tbody>
{
data?.map((item, index) => (
<tr>
<td>Name: </td>
<input
type="text"
required="required"
placeholder="Edit menu item"
name="age"
defaultValue={item?.name}
onChange={() => itemChange(item?.class, item?.id)}
>
</input>
{/* {item?.name} */}
{/* Full_Name: { item.name },
User_Email: { item.email } */}
</tr>
))
}
</tbody>
</table>
<Button onClick={() => saveMenu()}>save</Button>
</div>
)}
</div>
</div>
)
When i use input tag for objects, I need to manipulate them when i click the button. However, I dont know how many objects, so I cannot use state variables. Moreover, i need to know information from object itself when i change the object. Whole code is below.
import React, { useState } from 'react'
import Header from "../Components/common/header/header";
import Sidebar from "../Components/common/sidebar/Sidebar";/// IGNORE THIS PAGE
import useFetch from './useFetch';
import { Button } from 'antd';
function MenuEditer() {
const [newItem, setNewItem] = useState("")
const [edit, setEdit] = useState(false);
const [buttonPressed, setButtonPressed] = useState(false);
const { data, loading, error } = useFetch("http://localhost:3001/category/deneme");
const itemChange = async (clss, id) => {
alert("beginning of the func");
// while(!buttonPressed);
// alert("button pressed");
// if(clss === "category"){
// }
// if(clss === "item"){
// }
}
const saveMenu = async () => {
setButtonPressed(true);
setEdit(false);
}
const editMenu = async () => {
setEdit(true);
}
if (loading) {
return (
<div>
<div>
<Header />
<Sidebar />
</div>
<h1>LOADING ...</h1>
</div>
);
}
if (error) console.log(error);
return (
<div>
<div>
<Header />
<Sidebar />
<h1>Menu Edit Page</h1>
{edit === false ? (
<div>
<table>
<tbody>
{
data?.map((item, index) => (
<tr>
<td>Name: </td>
<td>{item?.name}</td>
{/* Full_Name: { item.name },
User_Email: { item.email } */}
</tr>
))
}
</tbody>
</table>
<Button onClick={() => editMenu()}>edit</Button>
</div>
) : (
<div>
<table>
<tbody>
{
data?.map((item, index) => (
<tr>
<td>Name: </td>
<input
type="text"
required="required"
placeholder="Edit menu item"
name="age"
defaultValue={item?.name}
onChange={() => itemChange(item?.class, item?.id)}
>
</input>
{/* {item?.name} */}
{/* Full_Name: { item.name },
User_Email: { item.email } */}
</tr>
))
}
</tbody>
</table>
<Button onClick={() => saveMenu()}>save</Button>
</div>
)}
</div>
</div>
)
}
export default MenuEditer;
How can I reach object itself from the array, or use useState hook without knowing the length of data? OR, can i write statements of function in onClick attribute? OR, can i use anything else for input form for specifically reach the object and updated string ? The issue may not be clear but I would be very appreciated to any idea. Thanks!
CodePudding user response:
you can use an object to handle the inputs data
at first use useEffect
to set the initial values of the state
Note make sure that the property name
for the HTML input is the same as the one that comes form the API the
const [formData, setFormData] = useState({})
useEffect(() => {
const copy = formData
data.forEach((item,index)=> {
copy["item" index] = {name: item.name, email: item.email}
setFormData(copy)
})
}, [])
then allow the event handler to automatically handle the change
const itemChange = (event, index) {
const copy = formData
const changedItem = copy["item" index]
changedItem[event.target.name] = event.target.value
setFormData(copy)
}
in the input element
<input
type="text"
required={true}
placeholder="Edit menu item"
name="age" // make sure the name is same as the property name that comes form the api
value={formData["item" index].age}
onChange={(e) => itemChange(e, index)}
/>