简体   繁体   English

从react.js中的数组拼接元素

[英]Splicing element from array in react.js

I want to splice element from array in my todo app. 我想在待办事项应用程序中从数组中拼接元素。 As per code the first element is getting removed even if I click 2nd or 3rd remove button. 根据代码,即使单击第二或第三删除按钮,第一个元素也会被删除。 Button used for removing element invokes remove(i) function,Here is my code for todo: 用于删除元素的按钮调用remove(i)函数,这是我要做的代码:

  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> 

You forgot to pass the index to the bind() for remove() . 您忘记了将索引传递给remove()bind() remove() Passing the index( i ) fixed this. 通过索引( i )可以解决此问题。 Hope it helps! 希望能帮助到你!

 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> 

You are concatenating an array with an object. 您正在将数组与对象连接在一起。

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

You forget a space before your className uses 您在className使用之前忘记了空格

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

In the remove function, don't use splice but concat/slice instead to avoid mutations 在删除功能中,不要使用拼接,而应使用concat / slice以避免突变

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

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