0

So I'm trying to build my portfolio site using React to practice. I want to have my projects, currently rendered from an array, to link to a project overview page that renders the correct data from the array onto the page.

const data = [
        {
    'name': 'Cady Studios',
    'date': 'January 2018',
    'type': 'UI/UX | Front End Development',
    'imageUrl': require('../images/projectOneImage.png'),
    'link': '',
    'brief': '',
    'tech': '',
},
    {
    'name': 'SWP Connect',
    'date': 'March 2018',
    'type': 'UI/UX',
    'imageUrl': require('../images/projectTwoImage.png'),
    'link': '',
    'brief': '',
    'tech': '',
},
{
    'name': 'Carzilla',
    'date': 'November 2017',
    'type': 'UI/UX',
    'imageUrl': require('../images/projectThreeImage.png'),
    'link': '',
    'brief': '',
    'tech': '',
},
{
    'name': 'Stone Mountain Park',
    'date': 'September 2017',
    'type': 'UI/UX',
    'imageUrl': require('../images/projectFourImage.png'),
    'link': '',
    'brief': '',
    'tech': '',
    }   
];


function Project(props){
return (
    <div>
        <a href={props.link} >
        <div className="project">
            <figure className="effect-sadie">
                <img className="projectImage img-fluid"
                    src={props.imageUrl}
                    alt={props.name}
                    />
                <figcaption>
                        <div className="projectInfoSmall">
                            <div className="projectType"><p>{props.type}</p></div>
                        </div>
                        <div className="projectTitle"><h2>{props.name}</h2></div>
                </figcaption>
            </figure>
        </div>
        </a>
    </div>
);
}

class ProjectsSection extends Component {
constructor(props) {
    super(props)
    this.state = {
        works: []
    }
}

componentWillMount() {
    this.loadWork()
}

loadWork() {
    const works = []
    data.map(item => works.push(item))
    this.setState({ works })
    setTimeout(() => {
        console.log(this.state)
    }, 2000)
}

render() {
    const projects = this.state.works.map((project, index) => <div className="grid"><Project 
            name={project.name}
            date={project.date}
            type={project.type}
            imageUrl={project.imageUrl}
            link={project.link}
            brief={project.brief}
            tech={project.tech}
            key={index}
        /></div>)

    return (
        <div className="container">
            <div className="project-section">
                <h2>Recent Projects</h2>
                    { projects }
                </div>
            </div>
    )
}
}

I assume that I'll need to use some conditional rendering to get what I'm wanting, but I am not sure where to begin. I've attempted to create the overview template, but have a feeling that I'm missing something. I know that I'll need ReactRouter's help in Linking to the page, but beyond that I'm stuck! Any help will be appreciated! Link to Github

function ProjectsTemplate(props) {
return(
        <div>
            <div className="projectHero">
                <div className="projectHeading">
                    <h1>{props.name}</h1>
                    <div className="projectInfoLeft">
                        <div className="projectRole">
                            <h5>Role</h5>
                            <p>{props.type}</p>
                        </div>
                        <div className="projectTech">
                            <h5>Tech</h5>
                            <p>{props.tech}</p>
                        </div>
                        <div className="projectDate">
                            <h5>Date</h5>
                            <p>{props.date}</p>
                        </div>
                    </div>
                    <div className="projectInfoRight">
                        <div className="projectBrief">
                            <h5>Brief</h5>
                            <p>{props.brief}</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}

class ProjectsPage extends Component {
render() {
    return(
        <div>
            <div className="container">
                <Header />
                <ProjectsTemplate />
            </div>
        </div>
    );
}
}
BThor
  • 1
  • Do you get anything rendered? – Yossi Apr 30 '18 at 19:29
  • Yeah, I've got the projects rendering properly on the homepage. I just don't know how to also pass the project data to the project overview page, depending on which project is clicked on the homepage. – BThor Apr 30 '18 at 19:35
  • Have you defined onClick in the project's div? This onclick should switch to the project's route. – Yossi Apr 30 '18 at 19:44
  • I haven't defined an onClick handler yet. Would this wrap the entire project div? Do you think you could provide an example or point me to one? Thanks for your help – BThor Apr 30 '18 at 21:25

1 Answers1

0

I believe that the following is in the right direction... It is not the full code, but it gives the idea. I didn't test the code, I leave it to you to do any changes, if required.

This, however, is not complete, since it only passes the project id, not the full object. I never did such a thing, but the following seems to provide a solution: How to pass parameters in react-router-dom Link?

Now to the changes.

Start by splitting ProjectsSection.js into two files: one with the ProjectsSection component, another with the Project component.

In App.js, include the two sepearte components, then change the existing code (where relevant) to the following code:

import { BrowserRouter, Route, Switch } from 'react-router-dom';

and:

  <BrowserRouter>
        <Route path="/" component={Header} />
        <Route path="/" component={Hero} />
        <Switch>
          <Route exact path="/" component={ProjectSection} />
          <Route path="/Projects/:projectId" component={Project} />
      </Switch>
  </BrowserRouter>

In the Project component, extract the project number by the following:

const projectId = this.props.match.params.projectId;

Now do the replacement of id with object...

Yossi
  • 5,577
  • 7
  • 41
  • 76
  • Wonderful feedback @Rahamin. I appreciate you taking the time to give an example! This gives me a clearer picture of what's needed. Thank you! – BThor May 01 '18 at 14:06
  • Sure. Hope it works. I just tried to give you a hook, didn't have time to give you the fish :) BTW, if you used redux, you could only pass the number, and both components could access the global state... – Yossi May 01 '18 at 14:30
  • So after a day of tinkering, I'm a bit farther along, but keep encountering errors. When adding this const projectId = this.props.match.params.projectId; I get an error message stating that "Cannot read property 'props' of undefined. And I think I stared at the sentence "do the replacement of id with object" so much that I've confused myself. If you can, could you elaborate on that? Things seem to be rendering, and the router is working properly. Just the data from the array object isn't being passed to the project page. – BThor May 02 '18 at 14:05
  • I'm getting somewhere. Slow and steady. I've now got the projects rendering the correct information to separate pages based on their id. Now onto the onClick event! :) – BThor May 02 '18 at 21:05
  • Just saw your message from 9 hours ago... I have never passed an object, so it miggt also take me time.. but your message from 2 hours ago seems to show that you are doing it by yourself. From my experience, struggling with things and solving them by yourself pays off in next projects. – Yossi May 02 '18 at 23:12
  • Is an onClick event needed? My suggestion to add it was written before I saw your code... aren't the tags in Project providing the required functionality? – Yossi May 02 '18 at 23:15
  • Yeah, you're right. It's much more satisfying to solve a problem yourself after a long grind! And yeah, there is no onClick event needed. Luckily, like you said, the routing/links handle all of that! – BThor May 03 '18 at 14:36
  • Not only satisfying, also pays off :) – Yossi May 03 '18 at 16:44