简体   繁体   English

事件更改时跨表保持状态

[英]Persisting state across tables on event change

I have a table of schedules that is rendered by a dropdown. 我有一个由下拉列表呈现的计划表。 Each schedule can then be marked for export via a slider, this will store the schedule id in scheduleIdsToExport and show that schedule in the export table. 每个调度然后可以通过滑块标记用于出口,这将存储在计划ID scheduleIdsToExport并显示在出口表的时间表。

But if I change the Select Query dropdown, which renders more schedules specific to that query, the schedules marked for export from the previous query disappear from the table. 但是,如果我更改“ Select Query下拉列表,该下拉列表会呈现特定于该查询的更多计划,则从上一个查询中标记为导出的计划将从表中消失。 I want the schedules marked for export to persist in the table no matter what query is selected from the dropdown. 无论从下拉列表中选择什么查询,我都希望标记为导出的计划在表中保留。

So I'm thinking I need to have something in my slider function to update state with the all the schedule objects marked for export and have them persist in the exported table. 所以我认为我需要在我的slider功能中使用标记为导出的所有计划对象来更新状态,并将它们保留在导出的表中。 I'm not exactly sure how to go about storing all the schedules to keep them in the exported table and have the scheduleIdsToExport array also keep the id 's of each schedule 我不确定如何存储所有日程表以将它们保存在导出的表中,并且让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);
        }
      );
    }
  };

The sandbox here will provide further explanation on what is happening. 这里的沙箱将提供有关正在发生的事情的进一步解释。

This is just chaotic! 这只是混乱!

The problem : Keep track from multiples list of items(schedules) that will eventually be added to another list schedulesToExport 问题:跟踪最终将添加到另一个列表schedulesToExport的项目(计划)的倍数列表

The Solution : 解决方案 :

  • Create a parent component that reflects the previously described state 创建反映先前描述的状态的父组件

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

Now we have a list of lists, that can be interpreted as a list of querys containing a list of schedules 现在我们有一个列表列表,可以解释为包含计划列表的查询列表

  • Render a select element to reflect each query: 呈现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> ) } 

What's happening? 发生了什么? We are just rendering the selected query by it's index and showing all it's respective schedules. 我们只是通过它的索引呈现所选查询并显示它的各自的时间表。

  • Implement the selectQuery and selectSchedule methods which will add the selected schedule in the list to export: 实现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) }) } 

That's it, now you a have a list of querys being displayed conditionally rendered selectedQuery props is just a index, but could be a property's name. 就是这样,现在你有querys列表显示有条件呈现selectedQuery道具只是一个指标,但可能是一个属性的名称。 You only see schedules from the current selected query, so when you click on schedule we just return it's index, and the state.querys[selectedQuery][index] will be your selected schedule, that is securely store in the state on a separated list. 您只能看到当前所选查询的计划,因此当您单击计划时我们只返回它的索引, state.querys[selectedQuery][index]将是您选择的计划,它将安全地存储在分隔列表中的状态中。

I have updated your sandbox here . 在这里更新了你的沙箱。

In essence, it does not work in your example because of the following: 从本质上讲,由于以下原因,它在您的示例中不起作用:

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

The value of schedules is always set to the current query , hence you end up showing schedules to export for the current query only. schedules的值始终设置为当前查询 ,因此您最终只显示要为当前查询导出的计划。

A solution that changes very little of your code is to ditch scheduleIdsToExport altogether, and use schedulesToExport instead. 一个只改变你的代码的解决方案是完全抛弃scheduleIdsToExport ,而是使用schedulesToExport Initially, we'll set schedulesToExport to an empty object; 最初,我们将schedulesToExport设置为空对象; we'll add schedules to it (keyed by schedule id) every time a schedule is selected - we'll delete schedules in the same way every time a schedule is unselected. 每次选择一个时间表时,我们都会向它添加时间表 (按时间表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
            });
        }
    };

    // ...
}

You would then render the schedules to export as follows: 然后,您将按以下方式呈现要导出的计划:

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

Again, see more details in sandbox here . 再次,在这里查看沙盒中的更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM