I am trying to do crud operation through json-server. The server looks like:
{
"product": [
{
"prod_name": "Product1",
"prod_price": "23451",
"prod_desc": "Lorem Ipsum",
"id": 1
},
{
"prod_name": "Product2",
"prod_price": "12345",
"prod_desc": "Lorem Ipsum",
"id": 2
}
]
}
It is working fine for get,post and delete. For edit I was sending the id through url, after receiving it I am trying to fetch the particular product using id, so that I can do the state update and using that state I will show the previous value in value attribute.
function EditProduct() {
const {pid}=useParams();
const [state,setState]=useState({})
const getProduct=async()=>{
const response=await axios.get(`http://localhost:1000/product/${pid}`)
return response;
}
useEffect(()=>{
getProduct().then(res=>{
console.log("Data to be edited: ",res.data)
setState(res.data)
console.log("Product: ",state);
})
.catch(res=>{
console.log("Error to find the product")
})
},[])
const handleSubmit=(event)=>{
}
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" name="prod_name" value={state.prod_name} onChange={(event)=>setState({prod_name:event.target.value})}/><br/><br/>
<input type="text" name="prod_price" value={state.prod_price} onChange={(event)=>setState({prod_price:event.target.value})}/><br/><br/>
<input type="text" name="prod_desc" value={state.prod_desc} onChange={(event)=>setState({prod_desc:event.target.value})}/><br/><br/><br/>
<input type="submit" value="Add" />
</form>
</div>
)
}
But the state updation is creating a problem. whenever the component is rerendering the state updation is happening.But until the rerendering it is showing blank. Is there any solution? What is the problem in my code?
Problem is inside your change handlers, you are not doing state update properly. setState
must receive whole object, not just one field as you are doing right now - thus forcing all other fields to be deleted whenever you update one field.
Rewrite to this:
<input type="text" name="prod_name" value={state.prod_name} onChange={(event)=>setState(prev => ({...prev, prod_name:event.target.value}))}/><br/><br/>
<input type="text" name="prod_price" value={state.prod_price} onChange={(event)=>setState(prev => ({...prev, prod_price:event.target.value}))}/><br/><br/>
<input type="text" name="prod_desc" value={state.prod_desc} onChange={(event)=>setState(prev => ({...prev, prod_desc:event.target.value}))}/><br/><br/><br/>
You will notice how I used prev
inside setState callback, and using that prev
you are retaining part of the old sate while updating just one desired field.