跨表保留有关事件更改的状态

时间:2019-04-04 18:36:38

标签: javascript reactjs

我有一个由下拉列表呈现的时间表表。然后可以通过滑块将每个时间表标记为要导出,这会将时间表ID存储在scheduleIdsToExport中,并在导出表中显示该时间表。

但是,如果我更改了Select Query下拉菜单,该下拉菜单呈现了更多针对该查询的计划,则标记为从上一个查询导出的计划将从表中消失。无论从下拉列表中选择了什么查询,我都希望标记为导出的计划保留在表中。

因此,我认为我需要在slider函数中添加一些内容,以使用标记为导出的所有计划对象更新状态并将它们保留在导出的表中。我不确定如何存储所有计划以将其保留在导出的表中,并且使scheduleIdsToExport数组也保留每个计划的id

  slider = ({ id, isExported }) => {
    if (isExported === true) {
      this.setState(
        {
          scheduleIdsToExport: [id, ...this.state.scheduleIdsToExport]
        },
        () => {
          console.log(this.state.scheduleIdsToExport);
        }
      );
    } else {
      const newArray = this.state.scheduleIdsToExport.filter(
        storedId => storedId !== id
      );
      this.setState(
        {
          scheduleIdsToExport: newArray
        },
        () => {
          console.log(this.state.scheduleIdsToExport);
        }
      );
    }
  };

沙箱here将对正在发生的事情提供进一步的解释。

2 个答案:

答案 0 :(得分:4)

这只是混乱!

问题:跟踪最终将添加到另一个列表的项目(日程表)的多个列表schedulesToExport

解决方案:

  • 创建一个反映先前描述状态的父组件

    class Container extends Component{
        state ={
            querys :[
                ['foo','lore ipsum','it\'s never lupus'],
                ['bar','ipsumlorem', 'take the canolli']
            ],
            selectedQuery : 0,
            schedulesToExport : []
       }
    }
    

现在我们有了一个列表列表,可以将其解释为包含时间表列表的查询列表

  • 呈现一个select元素以反映每个查询:

    render(){
      const { querys, selectedQuery } = this.state
      const options = querys.map((_, index) => (<option value={index}> Query: {index + 1}</option>))
      return(
        <div>
          <select onChange={this.selectQuery}>
            {options}
          </select>
          {
            querys[selectedQuery].map(schedule => (
              <button onClick={() => this.selectSchedule(index)}> Schedule: {schedule} </button>
            ))
          }
       </div>
     )
    }
    

发生了什么事?我们只是通过索引来显示所选查询,并显示其各自的时间表。

  • 实施selectQueryselectSchedule方法,这些方法将在列表中添加选定的计划以导出:

    selectQuery = e => this.setState({selectedQuery : e.target.value})
    
    selectSchedule = index => {
      const { selectedQuery } = this.state
      const selected  = this.state.querys[selectedQuery][index]
      this.setState({ 
        schedulesToExport: this.state.schedulesToExport.concat(selected) 
      })
    }
    

就是这样,现在您有了一个有条件显示的查询列表,selectedQuery道具只是一个索引,但是可以是属性的名称。您只会看到当前所选查询中的日程表,因此,当您单击日程表时,我们只返回它的索引,而state.querys[selectedQuery][index]将是您选择的日程表,并安全地存储在单独列表中的状态。

答案 1 :(得分:1)

我已经更新了您的沙盒here

本质上,由于以下原因,它在您的示例中不起作用:

schedules
    .filter(schedule =>
        scheduleIdsToExport.includes(Number(schedule.id))
    )
    .map(schedule => {
        return (
            <Table.Row>
                ...
            </Table.Row>
        );
     })

schedules的值始终设置为当前的查询,因此最终将显示仅导出当前查询的计划。

一种更改代码的方法很少,那就是完全放弃scheduleIdsToExport,而改用schedulesToExport。最初,我们将schedulesToExport设置为空 宾语;每次选择时间表时,我们都会向其中添加时间表(以时间表ID为键)-每次未选择时间表时,我们都会以相同的方式删除时间表。

class App extends React.Component {

    // ...

    slider = ({ id, isExported }) => {
        const obj = this.state.schedules.find(s => Number(s.id) === Number(id));
        if (isExported === true) {
            this.setState({
                schedulesToExport: {
                    ...this.state.schedulesToExport,
                    [id]: {
                        ...obj
                    }
                }
            });
        } else {
            const newSchedulesToExport = this.state.schedulesToExport;
            delete newSchedulesToExport[id];
            this.setState({
                schedulesToExport: newSchedulesToExport
            });
        }
    };

    // ...
}

然后您将呈现要导出的时间表,如下所示:

Object.keys(schedulesToExport).map(key => {
    const schedule = schedulesToExport[key];
    return (
        <Table.Row>
            ...
        </Table.Row>
     );
 })

同样,请在沙箱here中查看更多详细信息。