import React, {useEffect, useState} from 'react'
import axios from 'axios'
import '../App.css'
import { useNavigate } from 'react-router-dom'
import { gettingData } from '../api/getUserData'
import { handleLogout } from '../api/handleLogout'
import { getGroundNear } from '../api/getGroundNearby'
import { bookingSlot } from '../api/bookingSlot'
const Dashboard = () => {
const navigate = useNavigate()
const [userData, setUser] = useState(undefined)
const [groundData, setGroundData] = useState([])
const [currentTime, setCurrentTime] = useState(Date.now())
const [isOccupied, setIsOccupied] = useState(false)
axios.defaults.withCredentials = true;
useEffect(()=>{
gettingData(setUser)
},[])
useEffect(()=>{
console.log("usee 2")
if(userData){
console.log(userData)
getGroundNear(userData.pincode, 0, 50000, setGroundData)
}
},userData)
const handleBooking = (slotId, groundId, userId) => {
if(bookingSlot(slotId, groundId, userId)){
setIsOccupied(true)
}
}
return (
<div>
<button onClick={() => {handleLogout(navigate)}}>Logout</button>
<div>
<h3>Grounds</h3>
{groundData && groundData.length &&
groundData?.map((ground)=>{
return(
<div id='cards'>
<img src={ground.photo} alt='ground'></img>
<h4>{ground.ground}</h4>
<span>Type: </span><span>{ground.type}</span><br/>
<span>{ground.discription}</span>
<div className='timings'>
<div className='slots'>
{
ground?.slots?.map(slot => {
return (
<>
{/*I want this component to re-render whenver the button is clicked so that it has updated views of slot booking*/}
<div id='slot-id'>
{!slot.occupied ? (
<button onClick={() => handleBooking(slot._id, slot.ground_id, userData._id)}>{slot.time_start} - {slot.time_end}</button>
) : (
<button id='occupied-slot' style={{border: '3px dotted red', cursor: 'not-allowed', backgroundColor: '#FF999C'}}>{slot.time_start} - {slot.time_end}</button>
)}
</div>
</>
)
})}
</div>
</div>
</div>
)
})
}
</div>
</div>
)
}
export default Dashboard
Challenge: Re-rendering slot-id Div on Button Click in React
I’m working on a React component that displays bookable slots. Each slot has a button, and I want the entire slot-id div to re-render whenever a button is clicked.
In the provided code, the button click triggers the handleBooking function, but it doesn’t directly cause the slot-id div to re-render. This means the visual appearance won’t change unless the data source (e.g., an API call) updates the slot.occupied property outside of this component.
Desired Behavior: We want the slot-id div to re-render immediately after the button click, even if the external data source hasn’t been updated yet. This will provide a more responsive user experience by instantly reflecting the button click visually
2
Answers
You should create a separate component for the button, than you can just simply pass
slot.occupied
as a prop and let the deeper component apply the needed styling.Then wen the
slot.occupied
prop is changed, the deeper component will re-render.An example of the deeper component:
Which you can use in your
map()
To ensure the slot-id div re-renders immediately after a booking button is clicked in your React component, you should update your component’s state in a way that triggers a re-render. This can be done by updating the groundData array in the state to reflect the changes made by the booking. Here’s how you can modify your handleBooking function and other relevant parts of your code:
Step 1: Modify handleBooking
Update the handleBooking function to mark a slot as occupied directly in the state. This change in state will cause React to re-render the component:
Step 2: Adjust API Call
Ensure your bookingSlot function returns a promise that resolves to a boolean indicating whether the booking was successful. This allows the state update to happen only after confirming the booking:
Step 3: Ensure Reactivity in the Render Method
Ensure that the render method correctly uses the updated groundData from the state: