在react.js中拼接来自数组的元素

时间:2016-10-17 13:45:22

标签: css reactjs

我想在我的todo应用程序中拼接数组中的元素。根据代码,即使我单击第二个或第三个删除按钮,第一个元素也会被删除。用于删除元素的按钮调用remove(i)function,这是我的todo代码:

    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>

2 个答案:

答案 0 :(得分:1)

您忘记将索引传递给bind()的{​​{1}}。传递索引(remove())修复此问题。希望它有所帮助!

&#13;
&#13;
i
&#13;
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'));
&#13;
.strike {
  text-decoration: line-through;
}
&#13;
&#13;
&#13;

答案 1 :(得分: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 / slice来避免突变