Search code examples
reactjsmaterial-uireact-props

Navigate to next page on Table row click in React JS


I have a table where I display a list of data. On row click, I want to navigate the user to the next page. Following is my code:

export default class Venues extends Component {

  constructor(props) {
    super(props);
    this.state = {
      venues: [],
      isLoading: false,
    }
  }

  componentDidMount() {
    this.setState({isLoading:true});
    this.getVenueList();
  }

  getVenueList() {
    ApiService.getData(apiConfig.GET_VENUES, {
    }).then((res) => {
        if (res.data && res.data.error == null) {
            console.log(res.data);
            this.setState({ venues: res.data.result, isLoading: false });
            console.log(this.state.venues);
            console.log("venues");
        } else {
            alert(res.data.error.description );
        }
    });
  }
  
  handleRowClick() {
    this.props.history.push('/projectList');
  }

  addVenue() {
    this.props.history.push('/add_venue');
}

  render() {
    return (
      <div className="col-md-6 offset-md-3">
        <Form onSubmit={this.onSubmit}>
          <div className="form-group">
            <div style={divStyle}>
            <Typography variant="h4" style={style}>Venues</Typography>
                <div style={{
                    display: 'flex',
                    justifyContent: 'flex-end',
                    marginRight: '20px'
                }}> 
                <Button color="primary" onClick={() => this.addVenue()}>
                        Add Venue
                </Button></div>
              {this.state.isLoading ? (<div style={{
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center',
                    height: '100vh'
                }}><div className="spinner-border text-primary" role="status" >
                        <span className="sr-only">Loading...</span>
                    </div></div>) : (
                        <Table>
                            <TableHead>
                                <TableRow>
                                    <TableCell>S.No.</TableCell>
                                    <TableCell align="center">Venue Name</TableCell>
                                    <TableCell align="center">Role</TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody>
                                {this.state.venues.map(row => (
                                    <TableRow key={row.id} onClick={this.handleRowClick}>
                                        <TableCell component="th" scope="row">
                                            {this.state.venues.indexOf(row) + 1}
                                        </TableCell>
                                        <TableCell align="center">{row.venueName}</TableCell>
                                        <TableCell align="center">{row.venueAddress}</TableCell>
                                 </TableRow>
                                ))}
                            </TableBody>
                        </Table>
                    )}
            </div>
          </div>
        </Form>
      </div>
    );
  }
}

I am getting the following error on row click:

TypeError: Cannot read property 'props' of undefined I am getting this error on handleRowClick() function.

Can someone please help me with this?


Solution

  • i wrote sample code this .

    TableDialog.js

    import React from "react";
    import "./styles.css";
    import {
      Table,
      TableHead,
      TableRow,
      TableCell,
      TableBody
    } from "@material-ui/core";
    
    const TableDialog = (props) => {
      const venues = [
        { id: 1, venueName: "name1", venueAddress: "add1" },
        { id: 2, venueName: "name2", venueAddress: "add2" },
        { id: 3, venueName: "name3", venueAddress: "add3" }
      ];
      const handleRowClick = () => {
        props.history.push("/tableDetail");
      };
      return (
        <div className="App">
          <Table>
            <TableHead>
              <TableRow>
                <TableCell>S.No.</TableCell>
                <TableCell align="center">Venue Name</TableCell>
                <TableCell align="center">Role</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {venues.map((row) => (
                <TableRow key={row.id} onClick={handleRowClick}>
                  <TableCell component="th" scope="row">
                    {venues.indexOf(row) + 1}
                  </TableCell>
                  <TableCell align="center">{row.venueName}</TableCell>
                  <TableCell align="center">{row.venueAddress}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      );
    };
    export default TableDialog;
    
    

    Home.js

    import React from "react";
    import TableDialog from "./TableDialog";
    
    const Home = (props) => {
      console.log(props);
      return (
        <>
          <TableDialog {...props} />
        </>
      );
    };
    
    export default Home;
    

    App.js

    import React from "react";
    import "./styles.css";
    import Home from "./Home";
    import TableDetail from "./TableDetail";
    import { BrowserRouter, Switch, Route } from "react-router-dom";
    
    export default function App() {
      return (
        <div className="App">
          <BrowserRouter>
            <Switch>
              <Route path="/tableDetail" component={TableDetail}></Route>
              <Route path="/" component={Home}></Route>
            </Switch>
          </BrowserRouter>
        </div>
      );
    }
    
    

    Work Demo

    CodeSandbox

    Notable cases
    use a attribute component in Route

              <Route path="/tableDetail" component={TableDetail}></Route>
              <Route path="/" component={Home}></Route>
    

    and second
    pass props to child component.

    const Home = (props) => {
      console.log(props);
      return (
        <>
          <TableDialog {...props} />
        </>
      );
    };