0

I'm trying to learn React by building a very basic "portfolio" site with react-router. My main components are: , , and . On the 'Work' page you should be able to see all of the project titles and types. 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 to ? My structure:

  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
/*
Work
<Work/>
 */

import PROJECTS from '../PROJECTS';    

 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
/*
Project
<Project/>
*/

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
/*
 ProjectDetail
<ProjectDetail/>
*/

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

export default ProjectDetail;
PROJECTS.js
module.exports = [

{
    id: 0,
    title: 'Project 0',
    description: '0 Lorem ipsum dolor sit amet, consectetur adipisicing   elit. Quod dolor nobis qui est magnam magni, voluptatibus optio beatae tempore ducimus dicta ratione, iure explicabo vero, sed iusto sunt minima earum.',
    type: 'website',
    technologies: 'blah, blah, blah'
},

{
    id: 1,
    title: 'Project 1',
    description: '1 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod dolor nobis qui est magnam magni, voluptatibus optio beatae tempore ducimus dicta ratione, iure explicabo vero, sed iusto sunt minima earum.',
    type: 'website',
    technologies: 'blah, blah, blah'
},

{
    id: 2,
    title: 'Project 2',
    description: '2 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod dolor nobis qui est magnam magni, voluptatibus optio beatae tempore ducimus dicta ratione, iure explicabo vero, sed iusto sunt minima earum.',
    type: 'website',
    technologies: 'blah, blah, blah'
}

];

Since I don't ever explicitly use the component (its only called in the Routes), I'm not sure how to pass all of the project information to . Is there an easy way to do this, or should I think about structuring the app differently? Sorry for such a long post--this is my first time using React. Any help would be much appreciated.

olafsadventures
  • 151
  • 1
  • 10
  • As your question stands, it's a bit broad and that's a lot of code to sift through. Can you narrow it down to one small specific example of exactly what you'd like to achieve? – Josh Beam Dec 01 '16 at 00:04
  • I simply want to display data for the ProjectDetail component. There is no other component that calls it. I'm not sure how to pull props from the parent. – olafsadventures Dec 01 '16 at 00:14
  • Possible duplicate of [How to pass props to {this.props.children}](http://stackoverflow.com/questions/32370994/how-to-pass-props-to-this-props-children) – azium Dec 01 '16 at 00:24

2 Answers2

0

In react router v2/3 which it looks like you are using you just need to put the prop you want to pass onto the Route.

Here is an example that passes the title prop into app and uses it to render within the app. http://jsbin.com/tuwazeyuku/edit?html,js,output

<Route path="/" component={App} title="Hello Route"/>

Then access the prop like so: this.props.route.title

kwelch
  • 2,370
  • 22
  • 23
  • The example passes in the props.params, I will be passing in multiple props that will not be url params. – olafsadventures Dec 01 '16 at 02:57
  • Your example prop is static. I want the the prop to be dynamic depending on what the user clicks. – olafsadventures Dec 01 '16 at 03:18
  • You should be able to pass the props to the route as you would to any other child. I am not sure what you mean by dynamic. If it is an object pass that. The example was to show how you would pass it and how to receive it. The rest is exactly how you pass props to any other child. – kwelch Dec 01 '16 at 03:20
0

Im not sure If I get your problem in the right way, but... You want to have an access to data from component Project (project.title.. etc) at component ProjectDetail? You have already define a route which is responsible for:

<Route path="work/:id" component={ProjectDetail} />

You have actually two choices:

  1. Use some of state library (e.g Redux).

How? If you will decide to use Redux, you will be able to have global state. What does it mean? It means that in the component Project you will SET your state, to be more precise you will set your projects to state of your application. Thanks to that in ProjectDetail you will be able to get them. Whats about particular ID? In ProjectDetail you have access to your id parameter (of your project). Its all you need :) Global state contains ALL projects, so all you need to do it filter this collection by your received id.

if its too much...

  1. Receive ID and filter your projects.js

At ProjectDetails at componentDidMount method receive your project ID. Now in real world application usually you should make a REST call for external resource, which in your case is details of your project. (eg. yourEndpoint/prjects/{id}/details). You are using hardcoded projects, so just simulate behaviour of such at ProdutDetail component:

componentDidMount() {
  const id = this.props.params.id
  const project = PROJECTS.filter((el) => el.id === id));
  this.setState({
    project
  });
}

and render method of course will use this state variable:

render() {
    return (
        <div>
            {/* THIS IS THE INFORMATION I NEED ACCESS TO */}
            {this.state.project.title}
            {this.state.project.description}
            {this.state.project.type}
            {this.state.project.technologies}
        </div>
    )
  }

And my additional question is why you're using PROPS everywhere? If Redux is not used here component wont get rendered.

Hope it helps, good luck!

MariuszJasinski
  • 504
  • 3
  • 8