如何为屏幕上呈现的每个元素创建删除按钮? ReactJS

时间:2018-04-06 17:38:26

标签: reactjs react-native

我正在使用React做一个简单的todo应用程序,只是为了练习。如何在单击时删除列表项?

我想为我的数组的每个元素创建一个删除按钮,每次点击时,该元素都会被删除。

我制作了一个代码,但它没有用。

我的按钮代码:



handledelTodoItem(v){
  const { filtered } = this.state;
      
  return filtered
      .map((item) => {item.name}).forEach(function(i){
        if(this.state.filtered[i] == v){
         delete this.state.filtered[i]
      }
    });
  this.setState({
    filtered:this.state.filtered
  })
  console.log(this.state.filtered)
}




我的渲染代码:



  render() {
    let { filtered } = this.state;

    return (
      <div>
        <input type="text" onChange={ this.getValueInput }></input>
        <button className='search' onClick={this.filterNames}> Search </button>
        <button onClick={this.previousPage}> Previous </button>
        <button onClick={this.nextPage}> Next </button>
        <h3>Current Page: {this.state.currentPage}</h3>
        <ul>Names: {this.elementsOnScreen()}</ul>
        {filtered.map((v) => {
          return <div><h1 className="font"><button className="allbutton" onClick={this.handledelTodoItem.bind(this, v)}>DelTodoItem</button>{v}</h1></div>
          
        })}
      </div>
&#13;
&#13;
&#13;

所有没有它的代码:

&#13;
&#13;
class Pagination extends React.Component {
  constructor() {
    super();
    
    
    const peoples =[{id:0, name:"a"}, 
      {id:1, name:"b"}, 
      {id:2, name:"c"}, 
      {id:3, name:"d"}, 
      {id:4, name:"e"}, 
      {id:5, name:"f"}, 
      {id:6, name:"gg"}, 
      {id:7, name:"ff"}, 
      {id:8, name:"fg"},
      {id:9, name:"de"}, 
      {id:10, name:"gf"}, 
      {id:11, name:"gh"}];
    
    this.state = {
      elementsPerPage:3,
      currentPage:0,
      peoples,
      input: "",
      filtered: peoples,
    };

    this.nextPage = this.nextPage.bind(this);
    this.previousPage = this.previousPage.bind(this);
    this.filterNames = this.filterNames.bind(this);
    this.getValueInput = this.getValueInput.bind(this);
  } 
  
    getValueInput (value) {
    this.setState({ input: value.target.value });
  }
    
  filterNames (){
  const {peoples} = this.state;
   this.setState({
      filtered: peoples.filter(item => item.name.includes(this.state.input)),
      currentPage:0})
  } 
  

  elementsOnScreen() {
    const {elementsPerPage, currentPage, filtered} = this.state;
    return filtered
      .map((item) => <li>{item.name}</li>)
      .slice(currentPage*elementsPerPage, currentPage*elementsPerPage + elementsPerPage);
  }

 nextPage() {
         console.log(this.state.filtered)

    const {elementsPerPage, currentPage, filtered} = this.state;
    
    if ((currentPage+1) * elementsPerPage < filtered.length){
      this.setState({ currentPage: this.state.currentPage + 1 });
    }
  }
  
    previousPage () {
      const { currentPage } = this.state;
      if(currentPage - 1 >= 0){
         this.setState({ currentPage: this.state.currentPage - 1 });
      }

  }

  render() {
    return (
      <div>
        <input type="text" onChange={ this.getValueInput }></input>
        <button className='search' onClick={this.filterNames}> Search </button>
        <button onClick={this.previousPage}> Previous </button>
        <button onClick={this.nextPage}> Next </button>
        <h3>Current Page: {this.state.currentPage}</h3>
        <ul>Names: {this.elementsOnScreen()}</ul>
      </div>
    );
  }
}


ReactDOM.render(
<Pagination/>,
  document.getElementById('root')
)
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

代码存在很多问题。

您想要的解决方案的一部分将出现在您的代码中 return <div><h1 className="font"><button className="allbutton" onClick={this.handledelTodoItem.bind(this, v)}>DelTodoItem</button>{v.name}</h1></div> v</button>之间的</h1>变为{ {1}}。这是因为v.name是一个对象数组,您无法呈现对象。所以你必须访问每个对象的名称。

现在在你的控制台中你会发出警告:数组或迭代器中的每个子节点都应该有一个唯一的&#34;键&#34; prop。这是因为在ReactJS中,无论何时迭代数组并显示项目列表,列表中的每个元素都需要一个键。这样React可以确定哪些元素发生了变化,哪些元素都没有变化,因此当它重新渲染时,它只需要渲染那些变化的元素。

有两个地方有你的名单。一个在this.state.filtered函数中,一个在elementsOnScreen函数中。我已经为render函数添加了键,现在它看起来像这样

elementsOnScreen

elementsOnScreen() { const {elementsPerPage, currentPage, filtered} = this.state; return filtered .map((item) => <li key={item.id}>{item.name}</li>) .slice(currentPage*elementsPerPage, currentPage*elementsPerPage + elementsPerPage); } 函数中,render将如下所示

filtered.map

现在,当您点击按钮时,它不起作用。相反,它有一个错误,上面写着无法读取属性&#39;状态&#39;未定义。这是因为您对此的引用是错误的。您必须绑定它或使用箭头功能。我个人觉得箭头功能的使用更容易。你也不应该改变反应状态。阅读docs for using state correctly

您的{filtered.map((v) => { return <div key={v.id}><h1 className="font" ><button className="allbutton" onClick={this.handledelTodoItem.bind(this, v)}>DelTodoItem</button>{v.name}</h1></div> })} 功能有问题。我已对其进行了编辑,编辑已添加为评论。

handleTodoItem

现在您的最终代码如下所示

&#13;
&#13;
    handledelTodoItem=(v)=>{
      console.log(v);
      let { filtered } = this.state; // changed const to let
     // removed the return statement

   // the code here was wrong. The function below will delete the element with The
   // id that was passed to it from the array filtered.
  // then the state is changed to the new array.
    filtered.splice(filtered.map(e => e.id).indexOf(v.id),1)

    this.setState({
     filtered:filtered
    })
 }
&#13;
&#13;
&#13;

我建议你做几个reactjs教程,这将非常有帮助,并尝试在es6上做一些阅读。