如何将object.item [n]的setState嵌套在嵌套在对象数组中的数组中

时间:2017-09-23 15:11:29

标签: javascript reactjs ecmascript-6

我有以下数据结构:

const library = [
  {
    procedureName:'Build Foundations',
    id:1,
    tasks:[  
      {
        taskName:'dig at least 1m deep', isCompleted:false, procedureId:1
      },
      {
        taskName:'At least 50m wide digging', isCompleted:false, procedureId:1
      },
      {
        taskName:'Buy megazords', isCompleted:false, procedureId:1
      }
    ]
  }, 
  {
    procedureName:'Building the roof',
    id:2,
    tasks:[
      {
        taskName:'Constructed according to the project', isCompleted:false, procedureId:2
      },
      {
        taskName:'Protect wood from humidity', isCompleted:false, procedureId:2
      },
      {
        taskName:'Roof build with the correct angle', isCompleted:false, procedureId:2
      }
    ]
  } 
]

我希望我的函数onTaskToggle设置为library.tasks.isCompleted的状态,如下所示:library.tasks.isCompleted: !library.tasks.isCompleted (我希望能够区分某些项目的点击) 我不知道如何进入这种状态。

我应该以不同方式构建我的数据结构还是我缺少某些内容?

onTaskToggle = (task) => {
    const findProcedure = library => library.filter(procedure => procedure.id === task.procedureId);
    
    const findTask = tasks => tasks.filter(singleTask => singleTask.taskName === task.taskName);
    
    const toggledTask = findTask(findProcedure(this.state.library)[0].tasks);
    
    const procedureIndex =  this.state.library.indexOf(findProcedure(this.state.library)[0]);
    
    const toggledTaskIndex = this.state.library[procedureIndex].tasks.indexOf(toggledTask[0]);
    
    const insideProcedure = this.state.library[procedureIndex];
    
    const insideTask = this.state.library[procedureIndex].tasks.indexOf(toggledTask[0]);

    this.setState({
    // Stuck there  ...library
    })
}

我不确定是否需要它,但这就是我传递数据的方式:

// Main component

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      projects,
      library,
    }
  }

  onTaskToggle = (task) => {
    const findProcedure = library => library.filter(procedure => procedure.id === task.procedureId);
    
    const findTask = tasks => tasks.filter(singleTask => singleTask.taskName === task.taskName);
    const toggledTask = findTask(findProcedure(this.state.library)[0].tasks);
    const procedureIndex =  this.state.library.indexOf(findProcedure(this.state.library)[0]);
    const toggledTaskIndex = this.state.library[procedureIndex].tasks.indexOf(toggledTask[0]);
    const insideProcedure = this.state.library[procedureIndex];
    const insideTask = this.state.library[procedureIndex].tasks.indexOf(toggledTask[0]);
    this.setState({
  //    ...library
    })
}

  render() {
    const {projects, library} = this.state;
    return (
        <div>
          <Procedures library={library} onTaskToggle={this.onTaskToggle}/>
        </div>
    );
  }
}

export default class Procedures extends Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    } 
    render() {
        return (
            <div>
                    {
                        <ProceduresList library={this.props.library} onTaskToggle={this.props.onTaskToggle}/>
                    }
            </div>
        );
    }
}

//Mapping through procedures

const ProceduresList = props => {
    const list = props.library.map(procedure => {
        const { id, procedureName, tasks } = procedure;
        return(
            <div key={id}>
                <h4>{procedureName} </h4>
                <div><ListingTasks tasks={tasks} onTaskToggle={props.onTaskToggle}/></div>
            </div>
        )
    })
    return <div>{list}</div>
}
export default ProceduresList;

// Last Component where all the magic shall happen

const ListingTasks = (props) => {
  const list = props.tasks.map(task => { // under this line goes mapping through procedures
    const taskName = task.taskName;
    return <div key={taskName} onClick={() => props.onTaskToggle(task)}>{taskName}</div>
  })
  return <div>{list}</div> 
}
export default ListingTasks

1 个答案:

答案 0 :(得分:0)

onTaskToggle(task) {
    const { library } = this.state
    const procedure = Object.assign({}, library.find(proc => (proc.id === task.procedureId)))
    const procedureIndex = library.findIndex(prec => prec.id === procedure.id)

    procedure.tasks = procedure.tasks.map((tsk) => {
      if (tsk.taskName === task.taskName) {
        tsk.isCompleted = !tsk.isCompleted
      }
      return tsk;
    })

    library.splice(procedureIndex, 1, procedure)

    this.setState({ library })
  }