I have a React+ Rails app .I am facing a small prob with my react application. Whenever I make a post request I am navigated to a page,but I cannot see my card rendered.After I refresh the page I can see the card getting rendered AND it ever persists on the page .Why do I have to refresh the page though?How to solve this? Here is my code.I have added some MUI designing pardon me if thats confusing Reservation Form
function ReservationForm() {
const navigate = useNavigate();
const params = useParams();
const { user,errors,setErrors } = useContext(Cont);
const [reservationData, setReservationData] = useState({
name: "",
date: "",
time: "",
num: "",
contact: "",
occasion: "",
});
function handleReservationChange(event) {
setReservationData({
...reservationData,
[event.target.name]: event.target.value,
});
}
function handleReservationChangeWithNameAndValue(name, newValue) {
setReservationData({
...reservationData,
[name]: newValue,
});
}
function handleReservationSubmit(event) {
event.preventDefault();
const newReservation = {
...reservationData,
restaurant_id: params.id,
user_id: user.id,
};
fetch(`/reservations`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newReservation),
})
.then((r) => r.json())
.then(
setReservationData({
name: "",
date: "",
time: "",
num: "",
contact: "",
occasion: "",
})
);
navigate("/myreservations");
}
return (
<>
<div className="overlay3">
<Box
component="form"
sx={{
"& > :not(style)": { m: 1 },
}}
noValidate
autoComplete="off"
onSubmit={handleReservationSubmit}
>
<h1 className="editheadings">Reserve ️</h1>
<FormControl className="inputstyle">
<InputLabel htmlFor="component-outlined">Name</InputLabel>
<OutlinedInput
type="text"
name="name"
id="name"
value={reservationData.name}
onChange={handleReservationChange}
label="Name"
/>
</FormControl>
<br />
<FormControl name="date" className="inputstyle">
<LocalizationProvider
dateAdapter={AdapterDayjs}
name="date"
fullWidth
>
<DatePicker
label="Date"
name="date"
value={reservationData.date || null}
onChange={(newVal) =>
handleReservationChangeWithNameAndValue("date", newVal)
}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
</FormControl>
<FormControl className="inputstyle">
<LocalizationProvider dateAdapter={AdapterDayjs}>
<TimePicker
name="time"
label="Time"
value={reservationData.time || null}
onChange={(newVal) =>
handleReservationChangeWithNameAndValue("time", newVal)
}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
</FormControl>
<br />
<FormControl className="inputstyle">
<InputLabel htmlFor="component-outlined">No. of Guests</InputLabel>
<OutlinedInput
type="number"
name="num"
value={reservationData.num}
onChange={handleReservationChange}
/>
</FormControl>
<br />
<FormControl className="inputstyle">
<InputLabel htmlFor="component-outlined">Contact</InputLabel>
<OutlinedInput
type="tel"
name="contact"
value={reservationData.contact}
onChange={handleReservationChange}
placeholder="contact"
/>
</FormControl>
<br />
<FormControl className="inputstyle">
<InputLabel htmlFor="component-outlined">Occasion</InputLabel>
<OutlinedInput
type="text"
name="occasion"
value={reservationData.occasion}
onChange={handleReservationChange}
/>
</FormControl>
<Stack paddingLeft={15} direction="row" id="loginbutton">
<ColorButton variant="contained" type="submit">
{" "}
Reserve
</ColorButton>
</Stack>
</Box>
</div>
</>
);
}
export default ReservationForm;
My Reservations
import {useEffect, useState } from "react";
import ReservationCard from "./ReservationCard";
import { useContext } from "react";
import { Cont } from "../Cont";
function MyReservations(){
const {reservations,setReservations}=useContext(Cont);
useEffect(()=>{
fetch("/reservations")
.then(res=>res.json())
.then(reservationData=>{
setReservations(reservationData)
})
},[])
function handleUpdateReservation(updatedReservation) {
const updatedReservations = reservations.map((reservation) => {
if (reservation.id === updatedReservation.id) {
return updatedReservation;
} else {
return reservation;
}
});
setReservations(updatedReservations);
}
function handleCancel(reservationtodelete){
const newReservations=reservations.filter(r=>r.id !== reservationtodelete)
setReservations(newReservations)
}
const renderReservations=reservations.map((reservation)=>(
<ReservationCard key={reservation.id} reservation={reservation} handleCancel={handleCancel} onUpdateReservation={handleUpdateReservation} />
))
return(
<>
{renderReservations}
</>
)
}
export default MyReservations;
Reservation Card
function ReservationCard({ reservation, handleCancel, onUpdateReservation }) {
const { name, date, time, num, contact, occasion } = reservation;
const [isEditing, setIsEditing] = useState(false);
const handleReservationUpdate = (updatedReservation) => {
setIsEditing(false);
onUpdateReservation(updatedReservation);
};
function handleDeleteClick() {
fetch(`/reservations/${reservation.id}`, {
method: "DELETE",
});
handleCancel(reservation.id);
}
return (
<>
{isEditing ? (
<Box m={4} sx={{ width: 500 }}>
<div className="overlay2">
<EditReservationForm
reservation={reservation}
onUpdateReservation={handleReservationUpdate}
/>
</div>
</Box>
) : (
<>
<Box m={4} sx={{ width: 500 }}>
<Card width={5}>
<CardContent>
<Typography variant="h5" component="div">
{reservation.restaurant.name}
</Typography>
<br />
<Typography sx={{ mb: 1.5 }} color="text.secondary">
Guest Details
</Typography>
<Typography variant="h6" component="div">
{name}
</Typography>
<Typography variant="h6">{contact}</Typography>
<Typography variant="h6">Date:{date}</Typography>
<Typography variant="h6">Time : {time}</Typography>
<Typography variant="h6">Guests : {num}</Typography>
<Typography variant="h6">Occasion:{occasion}</Typography>
</CardContent>
<CardActions>
<Button onClick={() => setIsEditing((isEditing) => !isEditing)}>
{" "}
Modify Booking
</Button>
<Button onClick={handleDeleteClick}>Cancel Booking</Button>
</CardActions>
</Card>
</Box>
</>
)}
</>
);
}
export default ReservationCard;