Mapping Data - Can you teach me this

Hi there!
It’s been almost a few days I am trying to import data with Props and Map method without make it.

The objective is to display a super simple list inside Works.jsx.

If you have time and want to help and teach me how to do, here is the code:

APP.JSX

import React from "react";
import Navbar from "./Pages/Navbar";
import Home from "./Pages/Home";
import Works from "./Pages/Works";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

export default function App() {
    return (
        <Router>
            <Navbar />
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/works" element={<Works />} />
            </Routes>
        </Router>
    );
}

WORKSDATA.JSX

export default [
    {
        id: 1,
        client:"YXZ",
        project: "Landing Page"
    }
]

WORKS.JSX

import React from 'react'
import WorksData from "./Pages/WorksData";

export default function Works(props) {
    const singleWork = WorksData.map(single => {
        return (
            <div>
                <Works 
                key={single.id}
                single={single}
                />
            </div>
        )
    })
  return (
    <div>
        {props.single.client}
        {props.single.project}
    </div>
  )
}

Best
P.LEE

Well, right off the top of my head, “WORKSDATA.JSX” shouldn’t be called that because it’s not JSX, it should just be “.js”. And when you import it, you should call it “worksData” - PascalCase is usually reserved for classes, component, and enums.

So, you have this:

    const singleWork = WorksData.map(single => {
        return (
            <div>
                <Works 
                key={single.id}
                single={single}
                />
            </div>
        )
    })

which looks basically right - it will store an array of JSX elements in _singleWork _. But then you never use it.

You do this:

    <div>
        {props.single.client}
        {props.single.project}
    </div>

But that is trying to get that data of props. But it’s not on props. map does not put the data on props. props are data that come from outside, like passed from a parent component or provider or by an HOC. That is not happening here. This data is internal.

I would expect something like this:

    <div>
        { singleWork }
    </div>

React knows what to do with that, it sees a JS array of JSX elements - it will render them.




Oh wait, now I see that in your map function you are calling Works. I have no idea what that would do.

Let’s back up a little. Your data is an array, which implies to me that there could be more than one. So, “singleWork” isn’t the best name. And at some point you need to tell it how to render these things.

One simple option would be, if you think there is only one:

  return (
    <div>
        { worksData[0].client }
        { worksData[0].project }
    </div>
  )

If however, there may be more than one, then you want to use map

const renderedWorks = worksData.map(work => (
  <div key={ work.id }>
    <p>{ work.client }</p>
    <p>{ work.project}</p>
  </div>
)

return (
  <div>
    { renderedWorks }
  </div>
)

or some people might just cut out the middle-man:

return (
  <div>
    { worksData.map(work => (
      <div key={ work.id }>
        <p>{ work.client }</p>
        <p>{ work.project}</p>
      </div>
    )}
  </div>
)

The important thing is that props don’t enter into this. Your worksData is being imported into the file, not injected into the component by React. And renderedWorks is being generated inside the component.

1 Like

Hi… thanks for the help.
i actually fixed coding this.

import React from 'react'
import { portfolio } from './WorksData.jsx'

export default function work () {
    const workList = portfolio.map(item => 
        <div>
            key={item.id}
           {item.client}
           <br></br>
           {item.project}
           <hr />
        </div> 
        )
        return (
            <div>
                {workList}
            </div>

            )    
}

Is the code clean?

Sure, that looks better.

One thing:

        <div>
            key={item.id}

should be:

        <div key={item.id}>

And your component name “work” should be PascalCase.

If you wanted to clean things up a bit more, you could do something like:

const WorkItem = ({ id, client, project }) => (
  <div key={id}>
    { client }
    <br></br>
    { project }
    <hr />
  </div> 
)

and


const WorkList =  () = (
  <div>
    { portfolio.map(WorkItem) }
  </div>
 ) 

I’d put those each in their own file. I think that is a little cleaner, but that gets subjective.

1 Like