2016-10-17 106 views
0

我想在我的待辦事項應用中從數組拼接元素。按照代碼,第一個元素即使我點擊第二個或第三個刪除按鈕也會被刪除。用於去除元件按鈕調用刪除(I)的功能,這是我的代碼TODO:來自react.js中數組的拼接元素

class App extends React.Component { 
 

 
     constructor(){ 
 
     super(); 
 
     this.state={ 
 
      todo:[] 
 
     }; 
 
     }; 
 

 
     entertodo(keypress){ 
 
     var Todo=this.refs.inputodo.value; 
 
     if(keypress.charCode == 13) 
 
     { 
 
      this.setState({ 
 
      todo: this.state.todo.concat({Value:Todo, Decor:'newtodo animated fadeInLeft', checked:false}) 
 
      }); 
 
      this.refs.inputodo.value=null; 
 
     }; 
 
     }; 
 
     todo(text,i){ 
 
     return (
 
      <li onClick={this.completes.bind(this,i)}className={text.Decor}> 
 
      <input type="checkbox" onChange={this.todoCompleted.bind(this,i)}className="option-input checkbox" checked={text.checked} /> 
 
      <div key={text.id} className="item"> 
 
       {text.Value} 
 
       <button type="button" className="destroy" onClick={this.remove.bind(this)}>X</button> 
 
      </div> 
 
      </li> 
 
     ); 
 
     }; 
 

 
     remove(i){ 
 
     this.state.todo.splice(i,1) 
 
     this.setState({todo:this.state.todo}) 
 
     }; 
 
     todoCompleted(i){ 
 
     var todo={...this.state.todo} 
 
     if(todo[i].checked){ 
 
      this.state.todo[i].checked = false; 
 
      this.state.todo[i].Decor='newtodo' 
 
      this.setState({ 
 
      todo: this.state.todo 
 
      }); 
 
     } 
 
     else { 
 
      this.state.todo[i].checked = true; 
 
      this.state.todo[i].Decor= 'strike' 
 
      this.setState({ 
 
      todo: this.state.todo 
 
      }); 
 
     } 
 
     }; 
 
     allDone=()=>{ 
 
     var todo = this.state.todo; 
 
     
 
     todo.forEach(function(item) { 
 
      item.Decor = "newtodo animated fadeInLeft strike" 
 
     }) 
 
     this.setState({todo: todo}); 
 
     }; 
 
     completes(i){ 
 
    var todo={...this.state.todo} 
 
    if(todo[i].Decor==='newtodo'){ 
 
     this.state.todo[i].Decor='line' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    else { 
 
     this.state.todo[i].Decor= 'newtodo' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    }; 
 

 

 
     render() { 
 
      return (
 
      <div> 
 
       <h1 id='heading'>todos</h1> 
 
       <div className="lines"></div> 
 
       <div> 
 
        <input type="text" ref= "inputodo" onKeyPress={this.entertodo.bind(this)}className="inputodo"placeholder='todos'/> 
 
        <span onClick={this.allDone}id="all">x</span> 
 
       </div> 
 
       <div className="mainapp"> 
 
       <ul> 
 
       {this.state.todo.map(this.todo.bind(this))} 
 
       </ul> 
 
       </div> 
 
      </div> 
 
     ); 
 
     } 
 
     } 
 
     ReactDOM.render(<App/>,document.getElementById('app'));
.strike { 
 
    text-decoration: line-through; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script> 
 
<div id="app"></div>

class App extends React.Component { 
 

 
    constructor(){ 
 
    super(); 
 
    this.state={ 
 
     todo:[] 
 
    }; 
 
    }; 
 

 
    entertodo(keypress){ 
 
    var Todo=this.refs.inputodo.value; 
 
    if(keypress.charCode == 13) 
 
    { 
 
     this.setState({ 
 
     todo: this.state.todo.concat({Value:Todo, Decor:'newtodo animated fadeInLeft', checked:false}) 
 
     }); 
 
     this.refs.inputodo.value=null; 
 
    }; 
 
    }; 
 
    todo(text,i){ 
 
    return (
 
     <li ocClick={this.completes.bind(this,i)}className={text.Decor}> 
 
     <input type="checkbox" onChange={this.todoCompleted.bind(this,i)}className="option-input checkbox" checked={text.checked} /> 
 
     <div key={text.id} className="item"> 
 
      {text.Value} 
 
      <button type="button" className="destroy" onClick={this.remove.bind(this)}>X</button> 
 
     </div> 
 
     </li> 
 
    ); 
 
    }; 
 

 
    remove(i){ 
 
    this.state.todo.splice(i,1) 
 
    this.setState({todo:this.state.todo}) 
 
    }; 
 
    todoCompleted(i){ 
 
    var todo={...this.state.todo} 
 
    if(todo[i].checked){ 
 
     this.state.todo[i].checked = false; 
 
     this.state.todo[i].Decor='newtodo' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    else { 
 
     this.state.todo[i].checked = true; 
 
     this.state.todo[i].Decor= 'strike' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    }; 
 
    allDone=()=>{ 
 
    var todo = this.state.todo; 
 
    
 
    todo.forEach(function(item) { 
 
     item.Decor = "newtodo animated fadeInLeft strike" 
 
    }) 
 
    this.setState({todo: todo}); 
 
    }; 
 
    completes(i){ 
 
    var todo={...this.state.todo} 
 
    if(todo[i].Decor==='newtodo'){ 
 
     this.state.todo[i].Decor='line' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    else { 
 
     this.state.todo[i].Decor= 'newtodo' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    }; 
 

 
    render() { 
 
    return (
 
     <div> 
 
      <h1 id='heading'>todos</h1> 
 
      <div className="lines"></div> 
 
      <div> 
 
       <input type="text" ref= "inputodo" onKeyPress={this.entertodo.bind(this)}className="inputodo"placeholder='todos'/> 
 
       <span onClick={this.allDone}id="all">x</span> 
 
      </div> 
 
      <div className="mainapp"> 
 
      <ul> 
 
      {this.state.todo.map(this.todo.bind(this))} 
 
      </ul> 
 
      </div> 
 
     </div> 
 
    ); 
 
    } 
 
    } 
 
    ReactDOM.render(<App/>,document.getElementById('app'));
.strike { 
 
    text-decoration: line-through; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script> 
 
<div id="app"></div>

回答

1

你忘了通過指數到bind()remove()。通過索引(i)解決了這個問題。希望能幫助到你!

class App extends React.Component { 
 

 
    constructor(){ 
 
    super(); 
 
    this.state={ 
 
     todo:[], 
 
     finished: false, 
 
    }; 
 
    }; 
 

 
    entertodo(keypress){ 
 
    var Todo=this.refs.inputodo.value; 
 
    if(keypress.charCode == 13) 
 
     
 
    { 
 
     this.setState({ 
 
     todo: this.state.todo.concat({Value:Todo, Decor:'newtodo animated fadeInLeft', checked:false}) 
 
     }); 
 
     this.refs.inputodo.value=null; 
 
    }; 
 
    }; 
 
    todo(text,i){ 
 
    return (
 
     <li ocClick={this.completes.bind(this,i)}className={text.Decor}> 
 
     <input type="checkbox" onChange={this.todoCompleted.bind(this,i)}className="option-input checkbox" checked={text.checked} /> 
 
     <div key={text.id} className="item"> 
 
      {text.Value} 
 
      <button type="button" className="destroy" onClick={this.remove.bind(this, i)}>X</button> 
 
     </div> 
 
     </li> 
 
    ); 
 
    }; 
 

 
    remove(i){ 
 
    this.state.todo.splice(i,1) 
 
    this.setState({todo:this.state.todo}) 
 
    }; 
 
    todoCompleted(i){ 
 
    var todo={...this.state.todo} 
 
    if(todo[i].checked){ 
 
     this.state.todo[i].checked = false; 
 
     this.state.todo[i].Decor='newtodo' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    else { 
 
     this.state.todo[i].checked = true; 
 
     this.state.todo[i].Decor= 'strike' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    }; 
 
    allDone=()=>{ 
 
    var todo = this.state.todo; 
 
    var _this = this 
 
    todo.forEach(function(item) { 
 
     item.Decor = _this.state.finished ? "newtodo animated fadeInLeft" : "newtodo animated fadeInLeft strike" 
 
     item.checked = !_this.state.finished 
 
    }) 
 
    this.setState({todo: todo, finished: !this.state.finished}); 
 
    }; 
 
    completes(i){ 
 
    var todo={...this.state.todo} 
 
    if(todo[i].Decor==='newtodo'){ 
 
     this.state.todo[i].Decor='line' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    else { 
 
     this.state.todo[i].Decor= 'newtodo' 
 
     this.setState({ 
 
     todo: this.state.todo 
 
     }); 
 
    } 
 
    }; 
 

 
    render() { 
 
    return (
 
     <div> 
 
      <h1 id='heading'>todos</h1> 
 
      <div className="lines"></div> 
 
      <div> 
 
       <input type="text" ref= "inputodo" onKeyPress={this.entertodo.bind(this)}className="inputodo"placeholder='todos'/> 
 
       <span onClick={this.allDone}id="all">x</span> 
 
      </div> 
 
      <div className="mainapp"> 
 
      <ul> 
 
      {this.state.todo.map(this.todo.bind(this))} 
 
      </ul> 
 
      </div> 
 
     </div> 
 
    ); 
 
    } 
 
    } 
 
    ReactDOM.render(<App/>,document.getElementById('app'));
.strike { 
 
    text-decoration: line-through; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script> 
 
<div id="app"></div>

+0

感謝上面信息,確實愚蠢的錯誤。我需要一個更多的幫助。輸入字段旁邊的「x」觸發待辦事項列表,但無法切換。此外複選框不被處理 –

+0

@GauravSoni我沒有得到你。在我的例子中它工作正常。 –

+0

我不是在說刪除按鈕。我在說輸入字段右邊的'X',這是span元素並且在'allDone'函數上工作,我無法切換' –

0

您正在串聯與對象陣列。

this.state.todo.concat([{Value:Todo, Decor:'newtodo animated fadeInLeft', checked:false}]) 

你忘了一個空格className使用

onClick={this.completes.bind(this,i)} className={text.Decor}> 
onChange={this.todoCompleted.bind(this,i)} className 

之前在刪除功能,不要使用拼接,但CONCAT /片來避免突變

+0

有另一種方式來實現呢? –

+0

concat是好的,你是避免在你的狀態 – devside

+0

雅我明白,我嘗試了多次,但無法糾正它。此外,點擊單個列表項上的css更改不起作用 –