首页 > 解决方案 > 在反应中呈现嵌套 JSON 的最佳方法?

问题描述

我有一个 JSON 文件,我想渲染它以响应未知的键和值(只是它们的类型):

{
  "Day 1" :{
    "Chest": {
        "warmUp": ["parallel bar dips"],
        "main": ["Bench Press", "Inclined Bench press", "Decline Bench press"],
        "secondary": ["Dumbbell Flys", "Cable Crossover Flys", "Pec-deck Fly"]
      },
      "Biceps" : {
      "Lola": ["Barbell Curl", "Preacher Curl"],
      "bobo": ["Hammer Curls", "Cable Curl", "Dumbbell Curl"]
    }
  }

我想渲染它们,使它们看起来像这样

  <h2>Day </h2>
    <h4>Chest</h4>
        <h5>warmUp</h5>
         <ul>
          <li>Bench Press</li>
          <li>Inclined Bench press</li>
          <li>Decline Bench press</li>
         </ul>
        <h5>secondary</h5>
          <ul>
            <li>Dumbbell Flys</li>
            <li>Cable Crossover Flys</li>
            <li>Pec-deck Fly</li>
           </ul>

我有一个解决方案https://codesandbox.io/s/cold-sun-vprkl?file=/src/App.js

Object.entries(program).map((arrays) => {
    return arrays.map((renderArr, render_idx) => {
      if (render_idx === 0) {
        return render.push(<h2>{renderArr}</h2>);
      } else {
        for (const [muscleGroup, exerciseGroups] of Object.entries(renderArr)) {
          render.push(<h4>{muscleGroup}</h4>);
          for (const exerciseCategory in exerciseGroups) {
            render.push(<h5>{exerciseCategory}</h5>);
            exerciseGroups[exerciseCategory].map(
              (exercise, exercise_idx) => {
                return render.push(<li>{exercise}</li>);
              }
            );
           ;
          }
        }
      }
    });
  });

但我想知道是否有更好、更优雅的方法来做到这一点。此外,在我的解决方案中,我无法将 ul 标签包裹在列表项周围。

标签: javascriptreactjs

解决方案


我会在适当的小组件之间拆分逻辑以提高可读性并更接近第一个 SOLID 原则 - 单一职责。

const data = {
  'Day 1': {
    Chest: {
      warmUp: ['parallel bar dips'],
      main: ['Bench Press', 'Inclined Bench press', 'Decline Bench press'],
      secondary: ['Dumbbell Flys', 'Cable Crossover Flys', 'Pec-deck Fly'],
    },
    Biceps: {
      Lola: ['Barbell Curl', 'Preacher Curl'],
      bobo: ['Hammer Curls', 'Cable Curl', 'Dumbbell Curl'],
    },
  },
}

const Program = ({ program }) => {
  const days = Object.entries(program)

  return (
    <section className="Program">
      {days.map(([name, data], index) => (
        <ProgramDay name={name} data={data} key={index} />
      ))}
    </section>
  )
}

const ProgramDay = ({ name, data }) => {
  const parts = Object.entries(data)

  return (
    <div className="ProgramDay">
      <h2>{name}</h2>

      {parts.map(([name, data], index) => (
        <ProgramPart name={name} data={data} key={index} />
      ))}
    </div>
  )
}

const ProgramPart = ({ name, data }) => {
  const types = Object.entries(data)

  return (
    <div className="ProgramPart">
      <h2>{name}</h2>

      {types.map(([name, exercises], index) => (
        <ProgramExercises name={name} exercises={exercises} key={index} />
      ))}
    </div>
  )
}

const ProgramExercises = ({ name, exercises }) => {
  return (
    <div className="ProgramExercises">
      <h5>{name}</h5>

      <ul>
        {exercises.map((name, index) => (
          <li key={index}>{name}</li>
        ))}
      </ul>
    </div>
  )
}

ReactDOM.render(<Program program={data} />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>


推荐阅读