React-router: Passing props to children

- 1 answer

Ad

I'm trying to learn React by building a very basic "portfolio" site with react-router. My main components are: App, Work, Project and ProjectDetail. On the 'Work' page you should be able to see all of the project thumbnails and titles. Clicking on a specific project should route you to that project's detail page, which will include the rest of the project's details. How can I pass the props of Project to ProjectDetail?

My files:

main.js
/*
  Routes
*/

var routes = (
    <Router history={createHistory()}>
        <Route path="/" component={App}>
            <IndexRoute component={Work} />
            <Route path="work" component={Work} />
            <Route path="work/:id" component={ProjectDetail} />
            <Route path="about" component={About} />
        </Route>
    </Router>
);

ReactDOM.render(routes, document.getElementById('main'));

-

App.js
/*
  App
*/


class App extends React.Component {
    render() {
        return (
            <div>
                <h1>App</h1>
                <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/work">Work</Link></li>
                    <li><Link to="/about">About</Link></li>
                </ul>
                {this.props.children}
                <footer>footer</footer>
            </div>
        )
    }
}

export default App;

-

Work.js
class Work extends React.Component {
    render() {
        return (
            <div>
                <p>Work</p>
                <ul>
                    {/* Need to loop of all projects */}
                    {PROJECTS.map(project => (
                        <li key={project.id}>
                            <Project project={project} />
                        </li>
                    ))}
                </ul>
            </div>
        )
    }
}

export default Work;

-

Project.js
class Project extends React.Component {
    render() {
        var project = this.props.project;
        var linkTo = "/work/" + project.id;

        return (
            <Link to={linkTo}>
                {project.title}
                <span> </span>
                {project.type}
             </Link>
        )
    }
}

export default Project;

-

ProjectDetail.js
class ProjectDetail extends React.Component {
    render() {
        return (
            <div>
                {/* THIS IS WHAT INFORMATION I NEED */}
                {this.props.project.title}
                {this.props.project.description}
                {this.props.project.type}
                {this.props.project.technologies}
            </div>
        )
    }
}

export default ProjectDetail;

I can access the data in my Project component, but how can I pass that along to ProjectDetail since I never explicitly use the ProjectDetail component (only used in my routing)?

EDIT: I should add that I suppose I am technically not trying to pass the props to a child since Project is no longer rendered once you are routed to a ProjectDetail. Does that make this impossible?

Ad

Answer

Ad

You need to use the createElement handler for your routes to control the instancing of the route handler. There you can pass props around to the components. React-Router decouples mother-child components, any state propagation needs to be done in the routes.

Update Based on your edit, in your case ProjectDetail must re-query the applicable project using this.props.params.id, something like...

ProjectDetail.js

class ProjectDetail extends React.Component {
    render() {
        let project = PROJECTS.find((item)=>item.id == this.props.params.id);
        return (
            <div>
                {project.title}
                {project.description}
                {project.type}
                {project.technologies}
            </div>
        )
    }
}
Ad
source: stackoverflow.com
Ad