MarcL
MarcL

Reputation: 3593

React Router pass props to component rendered by <Link />?

I currently have the problem, that when I target a route with route parameters like: "/courses/:id", I want to render the "Course" component with the props that normally comes from "Courses" component.

So, I have to pass those props from Courses to Course component, but how do I do it if my Course component is dynamically rendered by a component in React?

class App extends Component {
  render () {
    return (
      <BrowserRouter>
        <div className="App">
          <Link to={`/users`}>Users link</Link>
          <a href="/courses">Courses link</a>
          <Switch>
            <Route path="/" exact render={() => (<h1>Hello World!</h1>)} />
            <Route path="/users" component={Users} />            
            <Route path="/courses/:id" exact component={Course} />
            <Route path="/courses" component={Courses} />
          </Switch>
        </div>
      </BrowserRouter>      
    );
  }
}

export default App;

My Courses:

class Courses extends Component {
    state = {
        courses: [
            { id: 1, title: 'Angular - The Complete Guide' },
            { id: 2, title: 'Vue - The Complete Guide' },
            { id: 3, title: 'PWA - The Complete Guide' }
        ]
    }

    render () {
        return (
            <div>
                <h1>Amazing Udemy Courses</h1>
                <section className="Courses">
                    {
                        this.state.courses.map( course => {
                            return (
                            <Link 
                                to={{
                                    pathname:`/courses/${course.id}`,
                                    state: {
                                        title: course.title
                                    }
                                }}
                                key={course.id}
                            >
                                <article className="Course" >
                                <Course 
                                    id={course.id}
                                    title={course.title}
                                />
                                </article>
                            </Link>
                            )
                        } )
                    }
                </section>
            </div>
        );
    }
}

export default Courses;

This is my single Course component, the problem here is, that in the /courses route, the Course components get rendered as an array where the props get simply passed from the Courses array to my Course components. But when I click on a Link from a single Course component, I still have to render that component with the original props that I get from the array normally, so I have to grab them from and pass them to my rendered component by .... I have currently done this with a ternary operator that asks from where the props are (from Courses or from Link), and if that prop exists, it gets rendered. But is there a better approach maybe? This looks more like a fiddled workaround for me than a good design practice:

class Course extends Component {

    render () {
        return (
            <div>
                {console.log("Props: ", this.props)}
                <h1>{this.props.title? this.props.title: this.props.location.state.title}</h1>
                <p>You selected the Course with ID: 
                {this.props.id ? this.props.id: this.props.match.params.id}</p>
            </div>
        );
    }
}

export default Course;

Upvotes: 0

Views: 122

Answers (1)

Wiktor Maciej
Wiktor Maciej

Reputation: 259

I would move the state of Courses class to App class and pass it to Courses as property. You can pass this array to Course too so you would have access to it.

To pass property to the component rendered by router use different syntax. Instead of:

<Route path="/courses" component={Courses} />

use:

<Route path="/courses" render={(props)=><Courses {...props} courses = {this.state.courses}/>} />

(Based on: https://tylermcginnis.com/react-router-pass-props-to-components/)

Upvotes: 1

Related Questions