简体   繁体   中英

Rendering into DOM for each element in object

I have a JS Object filled with objects nested within those. If you'd rather have specifics, it's a "projects" object for my portfolio, with 7 projects in it that each have a title, description, details and an image url. This is how it's set up:

const projects = {
  0: {
    title: "Project name",
    description:
      "A cool description",
    details: [
      "First detail",
      "Second point",
      "Third item"
    ].map(detail => <li>{detail}</li>),
    image: "image_url"
  },
  1: { ... },
  2: { ... },
  ...

Now, based on this data I want to render one div element per item into the DOM, which doesn't seem to be working well. I've tried multiple ways, and I ended up being able to pass the 'projects' constant as a prop to where I need it, but since it's an Object instead of an array, I can't seem to use the map method on it (you can see that I used that method to render list items).

Here's what I'm currently trying:

function ProjectList(props) {
  const projects = props.projects;
  const projectItems = projects.map(project => <h1>Test</h1>);

  return <ul>{projectItems}</ul>;
}

And then down in render function...

<ProjectList projects={projects} />

Expectations: 7 h1 tags saying Test (I think I could take it from there if this would render)

Good news: the projects constant within ProjectList does return the appropriate object.

Bad news: "projects.map is not a function"

So, basically what I guess I am asking is a way to effectively iterate through a nested Object and render an element into the DOM each time. I'm sorry if it's a very basic thing but this is my first react project and I've tried all I could think of.

Thanks a lot for the help!

As stated by someone else, you can't map an object, but you can map over the keys of the object using

Object.keys(projects).map( key => <h1>{projects[key].title}</h1>)

Since you are using integer based keys for your projects object, you'd be better off declaring it as an array like this:

const projects = [
    {
        title: "Project name",
        description: "A cool description",
        details: [
            "First detail",
            "Second point",
            "Third item"
        ].map(detail => <li>{detail}</li>),
        image: "image_url"
    },
    { ... },
    { ... }
]

Then you can just use

projects.map(project => <h1>Test</h1>);

if you need the index of the element for some reason, you can use

projects.map((project, index) => <h1>Project {project.title} is index {index}</h1>);

the big problem is that the projects is an Object, so does not have the map array function. Maybe this example it will be useful.

Example Map using React using Objecj as Array

const projects = {
  0: {
    title: "Project name",
    description:
      "A cool description",
    details: [
      "First detail",
      "Second point",
      "Third item"
    ],
    image: "image_url"
  },
  1: {
    title: "Project name 2",
    description:
      "A cool description",
    details: [
      "First detail",
      "Second point",
      "Third item"
    ],
    image: "image_url"
  }
};

function ProjectItem(props) {
  return (
    <li>{props.item.title}</li>
  );
}


function ProjectList () {

  const newProjects = Object.values(projects);
  console.log('teste',newProjects);

  return (
    <ul>
      {newProjects.map(item =>
        <ProjectItem key={item.title} item={item} />
       )}
    </ul>
  );
}

// ========================================

ReactDOM.render(
  <ProjectList />,
  document.getElementById('root')
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM