1

I'm having trouble developing a clean solution to rendering multiple child components from inside a container component.

I have a Store object in the following schema:

{
    "events": {
        "2017": {
            "March": {
                "event1": {
                    "type": "concert"
                },
                "event2": {
                    "type": "hockey"
                }
            }
        },
        "2018": {
            "January": {
                "event3": {
                    "type": "basketball"
                }
            }
        }
    }
}

I'd like the output to be formatted

<section>
    <ul><span>March 2017</span>
        <li>event1 - concert</li>
        <li>event2 - hockey</li>
    </ul>
    <ul><span>January 2018</span>
        <li>event3 - basketball</li>
    </ul>
</section>

My initial thought was to iterate through each layer from the parent/container component's render method, starting with:

class Events extends Component {
    render() {
        let key = 0

        return  (
            <section>
                Object.keys(this.props.events).map(year => {

                  /* continue iterations and build JSX here */  

                })
            </section>
        )
    }
}

But mapping three levels deep isn't very elegant this way, not to mention, I'm having trouble maintaining compliant JSX.

Is parsing this object into several presentational components, having each child component handle iteration at its own level the best way to approach this? If so, would I pass each layer of the object (ie: year, month) down as a prop?

1 Answer 1

1

What you can do to clean this up is create individual presentational components and pass the appropriate data for it to display.

const data = {
  "events": {
    "2017": {
      "March": {
        "event1": {
          "type": "concert"
        },
        "event2": {
          "type": "hockey"
        }
      }
    },
    "2018": {
      "January": {
        "event3": {
          "type": "basketball"
        }
      }
    }
  }
}
const MonthEvents = ({ month, data }) => {
  return (
    <ul>
      {Object.keys(data).map((event, index) => {
        return <li>{event} {data[event].type}</li>
      })}
    </ul>
  )
}
const YearEvents = ({ year, data }) => {
  return (
    <ul>
      {Object.keys(data).map((month, index) => {
        return [
          <span>{month} {year}</span>,
          <MonthEvents key={index} month={month} data={data[month]} />
        ]
      })}
    </ul>
  )
}

class Events extends React.Component {
  render() {
    return (
      <section>
        {Object.keys(data.events).map((year, index) => {
           return <YearEvents key={index} year={year} data={data.events[year]}/>
        })}
        </section>
    )
  }
}

Working CodeSandBox

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.