Crumblenautjs
Crumblenautjs

Reputation: 169

React v4 routing for dynamically created components

I have a list of objects that I'm using to create ReportCard components. When the user clicks on one of these ReportCards, I would like it to route to a ReportDetail component, getting the ID property of the ReportCard passed via URL params. The problem is the Match.Params object being received by the ReportDetail component returns as params: {id: ":id"}. I think the way I'm creating these components is what is causing the problem.

I've tried changing how the ReportCard components are being generated. By changing the level of where as well as the tags.

  1. Report Area components creates the ReportCard components based on the amount of report objects.
  2. Each ReportCard component has a link tag.
  3. All ReportCard components have 1 Route tag.
  4. I would like to pass the report.id from ReportCard into the Route URL parameter for ReportDetail.

Appreciate any help, sorry for all the code.

Report List:

    export const reports = [
        {
          id: 1,
          name: "Report 1",
          company: "Company, Inc",
          description: "Charts"
        },
        {
          id: 2,
          name: "Report 2",
          company: "Company, Inc",
          description: "Charts 2"
        },
        {
          id: 3,
          name: "Report 3",
          company: "Company, Inc",
          description: "Charts 3"
        },
        {
          id: 4,
          name: "Report 4",
          company: "Company, Inc",
          description: "Charts 4"
        },
        {
          id: 5,
          name: "Report 5",
          company: "Company, Inc",
          description: "Charts 5"
        },
        {
          id: 6,
          name: "Report 6",
          company: "Company, Inc",
          description: "Charts 6"
        },

     ]

Report Area:

 interface DetailParams {
     id: string;
 }

 interface DetailsProps {
     required: string;
     match ? : match <DetailParams> ;
 }

 export interface IAppState {
     reports: any[];
 }

 export default class ReportArea extends React.Component <DetailsProps,
     IAppState> {
     constructor(props: DetailsProps & IAppState) {
         super(props);
         this.state = reports;
     }

     public render() {

         var groupSize = 2;
         var rows = this.state.reports.map(function(report) {
             return <Link to = "/reports/:id"><ReportCard md={3}
             key = {report.id}><ReportCard></Link > ;

         }).reduce(function(row, element, index) {

             index % groupSize === 0 && row.push([]);
             row[row.length - 1].push(element);
             return row;

         }, []).map(function(rowContent, index) {

             return <Row key = {index}> {rowContent}</Row>;
         });

         return <div className = "windowlayout"> {
                 rows}<Route path = '/reports/:id'
         component = {ReportDetail}/> </div>;
     }
 }

ReportCard Component:

  export default class ReportCard extends React.Component<DetailsProps, 
    any> {
    props: any;
    constructor(props: DetailsProps) {
    super(props);
    }
  public render() {
      const match = this.props.match
      return (
      <div>
      <Card className="subPanel" key={this.props.id}>
        <CardImg className="imagesec" src="https://via.placeholder.com/150" 
         alt="Card image cap" />
      </Card>
      </div>     
        );
       }
     }

ReportDetail Component:

 interface DetailParams {
    id: string;
  }

  interface DetailsProps {
    required: string;
    match?: match<DetailParams>;
  }

export default class ReportDetail extends React.Component<DetailsProps,any> 
  {
   props: any;

   constructor(props: DetailsProps) {
     super(props);

  }

  public render() {
     const {match} = this.props;
     return (

        <div>
        <h2>
            {match.params.id}
        </h2>
        </div>
         )

         }

        }

Upvotes: 0

Views: 51

Answers (1)

Ryan Cogswell
Ryan Cogswell

Reputation: 81036

The issue is <Link to = "/reports/:id">. This syntax is what you want for the Route, but for the link you should have the actual id. Something like:

const path = "/reports/" + report.id;
return <Link to = {path}>...

Upvotes: 2

Related Questions