首页 > 解决方案 > 如何在 ReactJs 中处理垃圾邮件删除

问题描述

我有一个项目列表,每个项目旁边都有一个垃圾桶(即删除按钮)。由于有很多可能的结果,我显示 25 个结果,然后对其余结果进行分页(此时当用户单击下一页按钮时,我得到下一个结果)。

但是,我面临的问题是,一旦他们删除了一个项目,如果数据库中仍有项目,我想检索他们的下一个项目。

所以 30 个项目属于这个用户,他们看到 25 个,如果他们删除一个,下一个项目(项目 26)将从数据库中提取并显示。

如果他们想删除 5 个项目并一个接一个地单击,我认为这不会很难实现,我害怕会发生竞争情况,而不是拉 item26、item27、item28、item29、item30,它可能会拉出 item26 x 5。

我能想出的唯一想法是,我拉的比我展示的要多,如果我展示 25 条记录,我拉 35 条记录,然后在每条记录被删除后继续重新填充该存储桶。

但是,我不确定如果没有足够的物品来补充桶,我将如何补充额外的桶以及如何处理的场景。

我正在使用 Reactjs、Mobx 和 Mobx 状态树。

我还没有任何代码,因为我不知道该走哪条路。

标签: javascriptreactjsaxiosmbox

解决方案


这就是我会做的:

  1. 在状态内创建一个数组来保存当前正在删除的项目
  2. 在我的删除功能中检查该项目当前是否正在被删除
  3. 如果被删除,什么也不做
  4. 如果不是,则将该项添加到数组中,调用 axios.delete() 然后从数组中删除该项

class PreventSpam extends React.Component {
  constructor(props){
    super(props);
    //Example data
    const exampleList = [{id: 1, name: "One"},
                         {id: 2, name: "Two"},
                         {id: 3, name: "Three"},
                         {id: 4, name: "Four"}]
    //State of the current component
    this.state={
      Deleting: [],
      items: exampleList
    }
    
    this.deleteItem = this.deleteItem.bind(this);
    this.loadNext = this.loadNext.bind(this);
  }
  
  deleteItem(item){
     //Remove element from my state
     let newItems = this.state.items.filter(it=> it.id !== item.id);
     this.setState({
     		items: newItems
     });
     
     //If this items is currently being deleted, return;
     if(this.state.Deleting.indexOf(item.id) !== -1){
     	 console.log("wait for this deletion to complete")
       return;
     }
     
     //Add the item to the deleting array
     this.setState((state,props)=> ({
       Deleting: [...state.Deleting, item.id]
     }));
     
     //call delete with axios
     axios.delete(`url/${item.id}`).then(()=>{
     			//Delete successful, update the deleting list
          let newDeleting = [...this.state.Deleting];
          let deletedIndex = newDeleting.indexOf(item.id);
          newDeleting.splice(deletedIndex, 1);
          this.setState({Deleting: newDeleting});
   				
          
          //Load next item
   				loadNext();
     }).catch(error => {
     			//Opt 1: add the item back to the state on error
          //Opt 2: alert the user
          //Opt 3: ?????
     })
  }
  
  //Loads the 25th or last item on the database
  loadNext(){
    axios.get("apiCall").then(response => {
      let newItem = response.data;
    });
  }
  render() {
    const {items} = this.state;
    return (<div>
      <table>
         <tbody>
           {items.map((item,index)=>{
             return (
               <tr key={index}>
                 <td>{item.id}</td>
                 <td>{item.name}</td>
                 <td><button onClick={() => this.deleteItem(item)}>Delete</button></td>
               </tr>
             )
            })
           }
        </tbody>
      </table>
      
    </div>);
  }
}

ReactDOM.render(
  <PreventSpam  />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>


推荐阅读