3

I am using react-router v4.2.2 and am trying to use a function to spit out a list of routes with a component property value of "project.title", taken from a reducer I am using. However, when I write:

return <Route key={i} exact path={`/${project.title}`} exact component={project.title}/>

using the project.title part results in this error:

Failed prop type: Invalid prop component of type string supplied to Route, expected function.

but when I replace project.title with an actual component like Project1:

return <Route key={i} exact path={`/${project.title}`} exact component={Project1}/>

then it's fine.

Is there a way I can use the titles of each project, from my reducer, in this function, without this error popping up?

here is the whole container code, in case it's helpful:

import React from 'react';
import Project1 from '../components/project1.js';
import { connect } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import { withRouter } from 'react-router';
import ProjectCards from '../containers/project_cards.js';

class App extends React.Component{
    render() {
        var createRoutes = this.props.projects.map((project, i) => {
            return <Route key={i} exact path={`/${project.title}`} exact component={project.title}/>
        });
        return (
            <Switch>
                <Route exact path="/" component={ProjectCards}/>
                {createRoutes}
            </Switch>
        );
    }
}

function mapStateToProps(state) {
    return {
        projects: state.projects
    };
}

export default withRouter(connect(mapStateToProps)(App));

1 Answer 1

2

You can't just pass a string as the component if a route -- it expects an actual component. What I would recommend is saving all your components in some kind object which then you can access:

const projects = {
  Project1,
  …
};
…
<Route key={i} exact path={`/${project.title}`} exact component={projects[project.title]}/>
Sign up to request clarification or add additional context in comments.

2 Comments

I placed an object in the render function, and am trying to get all the links to direct to the first project (component={projects[1]}) just to test that this works, but now no component is being rendered when the project rerenders after a card has been clicked :/
oh! I just replaced that code with the exact code you suggested: projects[project.title] and this worked! I'm sorry, I don't know why I didn't do that to start off with- the logic was unfamiliar to me and I think I got confused and tried to get to the first project in the object, as though the object was placed in an array of objects. Sorry about that, and thank you so much for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.