Shantanu Kondekar
Shantanu Kondekar

Reputation: 45

React-rendering specific data using button click

For my project, I was trying to render the specific doctor details when we click on "View details" button. Just like this -

Doctors List Component Card Component

How can I filter the specific doctor data to render it on Card component on ButtonCl?. Currently I am getting the entire data on card component. And on onClick event, I am calling the navigate function to render the Card component. Due to which I am not able to transfer the specific doctors data

Doctors List Component

Card Component

Here's my code -- RoutingController.js

class RoutingController extends React.Component {
constructor() {
    super();
    this.state = {
        doctorsList: [
            {
                id: 1,
                doctorName: 'Alexis Rodriguez',
                speciality: 'PULMONOLOGIST',
                ratings: 5,
            },
            {
                id: 2,
                doctorName: 'Zeph Gonzales',
                speciality: 'GENRAL_PHYSCIAN',
                ratings: 5,
            },
            {
                id: 3,
                doctorName: 'Virginia Wiggins',
                speciality: 'Dentist',
                ratings: 4,
            }

        ]
    }
}
render() {
    return (
        <Router>
            <Routes>
                <Route path="/" element={<Home doctorsList={this.state.doctorsList} />} />

                <Route path="/doctordetails" element={<ViewDoctorDetails doctorDetails={this.state.doctorsList} />} />

            </Routes>
        </Router>
    );
}

DoctorListComponent.js

    function DoctorListFunctional(props) {

return (
    <div className="main-container">
          {
             props.doctorsListArray.map(doc => {
                    return <div className="doc-container" key={doc.id}>
                        <Paper elevation={10} style={paperStyle}>
                            <Grid align='center'>
                                <div className="doctor-container">
                                    <h3 align='start'>Doctor Name: <span className="grid-item">{doc.doctorName}</span></h3>
                                </div>

                            </Grid>
                            <Grid align='center'>
                                <div className="doctor-details-container">
                                    <h5 align='start'>Speciality: <span className="grid-item">{doc.speciality}</span> </h5>
                                    <h5 align='start'>Ratings:<Rating name="read-only" value={doc.ratings} readOnly /></h5>

                                </div>
                            </Grid>
                            <Stack
                                direction="row"
                                alignItems="flex-end"
                                spacing={3}
                            >
                                <Button className={classes.MuiButtonControlroot} color='primary' variant='contained' onClick={() => onClick()}>
                                    Book Appointment
                                </Button>

                                <Button className={classes.MuiButtonControlroot} color='success' variant='contained' onClick={() => {
                                    navigate("/doctordetails");
                                }}> **Here due to navigate function, I am not able to filter and transfer the specific doctor data to the next card component**
                                    View Details
                                </Button>

                            </Stack>
                        </Paper>
                    </div>
                })
            }

        </Grid>
    </div>

)
}

ViewDoctorDetailsCardComponent.js

function ViewDoctorDetails(props) {
const navigate = useNavigate();
return (
    <div className="main-container">
        {
            props.doctorDetails.map((doctor => {
                console.log(doctor);
                return (
                <div key={doctor.id}>
                    {doctor.doctorName} &nbsp;
                    {doctor.speciality} &nbsp;
                    {doctor.ratings} &nbsp;


                </div>
                )
            }))
        }

Upvotes: 3

Views: 1278

Answers (2)

Drew Reese
Drew Reese

Reputation: 203218

I suggest adding a doctor id route match parameter in the path that you can filter the passed doctors list prop.

<Route
  path="/doctordetails/:id"
  element={<ViewDoctorDetails doctorDetails={doctorsList} />}
/>

In ViewDoctorDetails filter by the id match param. Note the id property in the data is type number and that URL path values will always be type string, so remember to ensure you use a type safe equality check. Here convert the doctor.id property to a string.

import { useParams } from 'react-router-dom';

function ViewDoctorDetails(props) {
  const { id } = useParams();
  return (
    <div className="main-container">
      {props.doctorDetails
        .filter((doctor) => doctor.id.toString() === id.toString())
        .map((doctor) => (
          <div key={doctor.id}>
            {doctor.doctorName} &nbsp;
            {doctor.speciality} &nbsp;
            {doctor.ratings} &nbsp;
          </div>
        ))
      }
    </div>
  );
}

Edit react-rendering-specific-data-using-button-click

Alternatively you could send the specific doctor details in route state.

<button
  ...
  onClick={() => {
    navigate("/doctordetails", { state: { doctor: doc } });
  }}
>
  View Details
</button>

...

<Route path="/doctordetails" element={<ViewDoctorDetails />} />

...

function ViewDoctorDetails(props) {
  const { state } = useLocation();
  const { doctor } = state || {};
  return (
    <div className="main-container">
      <div>
        {doctor.doctorName} &nbsp;
        {doctor.speciality} &nbsp;
        {doctor.ratings} &nbsp;
      </div>
    </div>
  );
}

Edit react-rendering-specific-data-using-button-click (forked)

Upvotes: 1

Jacob Botha
Jacob Botha

Reputation: 78

Firstly, you don't need to save the doctor's details list as part of the state, but simply as a standard array. Then you can just store the selected doctor's id as part of the state, and set the selected doctor's details when you click the view details button.

constructor() {
    super();
    this.state = {
        selectedDoc = null
    }
    this.doctorsList = [
...

Secondly, when you navigate to a new page you should most likely just request the details of that particular doctor from your backend and as such you will need to have the ID in the url. But why not just use a modal or drop down to display the details (since react really promotes using a single page application approach)

Nevertheless, you can still pass the data you require to the next page using the react router (how to pass props one page to another page via react router?)

Upvotes: 1

Related Questions