React - how to map nested object values?

前端 未结 3 765
野趣味
野趣味 2020-12-30 15:37

I am just trying to map nested values inside of a state object. The data structure looks like so:

I want to map each milestone name and then all tasks insid

相关标签:
3条回答
  • 2020-12-30 15:55

    You can use nested maps to map over the milestones and then the tasks array:

     render() {
      return (
        <div>
          {Object.keys(this.state.dataGoal.milestones).map((milestone) => {
            return (
              <div>
                {this.state.dataGoal.milestones[milestone].tasks.map((task, idx) => {
                  return (
                  //whatever you wish to do with the task item
                  )
                })}
              </div>
            )
         })}
        </div>
      )
    }
    
    0 讨论(0)
  • 2020-12-30 16:00

    What you want is flatMap. flatMap takes an array and a function that will be applied to each element in the array, which you can use to (for example) access properties inside each object in the array. It then returns a new array with the returned values from its lambda:

    function flatMap(arr, lambda) {
      return Array.prototype.concat.apply([], arr.map(lambda))
    }
    

    In our case, we don't have an array, we have an object so we can't use flatMap directly. We can convert the object to an array of its properties' values with Object.values and then make a function that accesses the object with the passed key:

    function tasksFromDataGoal(key) {
      return flatMap(Object.values(dataGoal[key].milestones), milestone => milestone.tasks)
    }
    

    Working example:

    function flatMap(arr, lambda) {
      return Array.prototype.concat.apply([], arr.map(lambda))
    }
    
    function tasksFromDataGoal(key) {
      return flatMap(Object.values(dataGoal[key].milestones), milestone => milestone.tasks)
    }
    
    const dataGoal = { 123: { milestones: { milestone1: { tasks: ['a', 'b'] }, milestone2: { tasks: ['c', 'd'] } } } }
    
    alert(tasksFromDataGoal('123'))

    Author of this implementation of flatMap: https://gist.github.com/samgiles/762ee337dff48623e729

    0 讨论(0)
  • 2020-12-30 16:21

    Managed to refactor the render method:

      render() {
        return(
          <div>
            {Object.keys(this.state.dataGoal).map( (key, index) => {
              const newDataGoal = this.state.dataGoal[key].milestones;
    
              return <div key={key}>
    
                       <header className="header">
                         <h1>{this.state.dataGoal[key].name}</h1>
                       </header>
                       <Wave />
    
                       <main className="content">
                         <p>{this.state.dataGoal[key].description}</p><br /><br />
    
                           {Object.keys(this.state.dataGoal[key].milestones).map( (milestoneKey) => {
                             const milestonesData = this.state.dataGoal[key].milestones[milestoneKey];
    
                             return <div className="milestone-wrap" key={milestoneKey}>
                                      <label className="milestone-label">{milestonesData.name}</label>
    
                                        {Object.keys(milestonesData.tasks).map( (taskKey) => {
                                          return <div className="task clearfix" key={taskKey}>
                                                      <input
                                                        className="checkbox-rounded"
                                                        name="task"
                                                        type="checkbox"
                                                        checked={milestonesData.tasks[taskKey].done}
                                                        onChange={(e) => this.handleInputChange(e, key, taskKey)} />
                                                      <div className="task-content">
                                                        <p className="task-name">{milestonesData.tasks[taskKey].name}</p>
                                                        <p className="task-date">{milestonesData.tasks[taskKey].finishDate}</p>
                                                      </div>
                                                 </div>
    
                                        })}
    
                                    </div>
    
                           })}
                       </main>
    
                     </div>
              })}
          </div>
        );
      }

    0 讨论(0)
提交回复
热议问题