事件更改时跨表保持状态

问题描述 投票:4回答:2

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

但是,如果我更改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将提供有关正在发生的事情的进一步解释。

javascript reactjs
2个回答
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>
     );
 })

再次,请参阅sandbox here中的更多详细信息。


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]将是您选择的计划,它将安全地存储在分隔列表中的状态中。

© www.soinside.com 2019 - 2024. All rights reserved.