2017-07-24 22 views
1

我正在研究一个todo应用程序来理解反应的力量。我创建了3个组件,我将在下面向您展示。所以我想从位于其他组件中的数组状态中删除待办事项。React通道支持其他组件从状态数组中删除

看看下面我的组件。

这是我TodoAppComponent:

import AddTodoComponent from '../AddTodoComponent/AddTodoComponent'; 

class TodoAppComponent extends Component { 
    render() { 
    return (
     <div id="page-content-wrapper"> 
      <div className="container"> 
       <div className="row"> 
        <div className="col-lg-6 col-lg-offset-3"> 
         <h1 className="m-b-md">What needs to be done?</h1> 

         <AddTodoComponent></AddTodoComponent> 
        </div>       
       </div> 
      </div> 
     </div> 
    ); 
    } 
} 

export default TodoAppComponent; 

在这里,我有TodoItemComponent:

class TodoItemComponent extends Component { 
    deleteTodo(todo){ 
     console.log('deleteTodo', todo); 
     this.props.onDelete(this.props.todo); 
    } 



    render() { 
     console.log('this.props.todo', this.props.todo); 

return (
    <div>    
     <li className="list-group-item todo-item"> 
      <button className="btn btn-xs btn-react btn-circle m-r-md"> 
       <span className="fa fa-check"></span> 
      </button> 
      {this.props.todo} 
      <span className="pull-right"> 
       <button className="btn btn-xs btn-react btn-circle m-r-xs"> 
        <span className="fa fa-pencil-square-o"></span> 
       </button> 

       <button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo.bind(this.props.todo)}> 
        <span className="fa fa-trash-o"></span> 
       </button> 
      </span> 
     </li> 
    </div> 
); 

}}

出口默认TodoItemComponent;

class TodoItemComponent extends Component { 
    deleteTodo(){ 
    // this.setState({ 
    // data: update(this.state.data, {$splice: [[index, 1]]}) 
    // }) 
    console.log('deleteTodo', this.props.todo); 
    } 


    render() {  
    console.log(this.props.todo, this.props.title); 

    return (
     <div>    
      <li className="list-group-item todo-item"> 
       <button className="btn btn-xs btn-react btn-circle m-r-md"> 
        <span className="fa fa-check"></span> 
       </button> 
       {this.props.todo} 
       <span className="pull-right"> 
        <button className="btn btn-xs btn-react btn-circle m-r-xs"> 
         <span className="fa fa-pencil-square-o"></span> 
        </button> 

        <button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo}> 
         <span className="fa fa-trash-o"></span> 
        </button> 
       </span> 
      </li> 
     </div> 
    ); 
    } 
} 

export default TodoItemComponent; 

这里是AddTodoComponent:

import TodoItemComponent from '../TodoItemComponent/TodoItemComponent'; 

class AddTodoComponent extends Component { 
    constructor(props) { 
     super(props); 

     this.state = { 
      todo: '', 
      todoArray: [] 
     }; 
    } 

    addTodo(e){ 
     this.setState({ todo: e.target.value }); 
     this.state.todoArray.push(<TodoItemComponent todo={this.state.todo} onDelete={this.delete}></TodoItemComponent>); 
    } 

    delete(index){ 
    //  this.setState({ 
    //   todoArray: update(this.state.todoArray, {$splice: [[index, 1]]}) 
    //  }); 

     console.log('testDelete', this.state.todoArray); 
    } 

    handleChange(e){ 
     this.setState({ todo: e.target.value }); 
    } 

    render() { 
     return (   
      <div> 
       <div className="input-group m-b-md"> 
        <input type="text" className="form-control add-todo" placeholder="Todo..." value={this.state.todo} onChange={this.handleChange.bind(this)} /> 
        <span className="input-group-btn"> 
         <button className="btn btn-react" type="button" onClick={this.addTodo.bind(this)}>Add</button> 
        </span> 
       </div> 
       <ul className="list-group"> 
        {this.state.todoArray} 
       </ul> 
      </div> 
     ); 
    } 
} 

export default AddTodoComponent; 

正如你看到的我尝试删除按钮点击时登录this.props.todo,所以当它发射出的TodoItemComponent deleteTodo function。它返回我Uncaught TypeError: Cannot read property 'props' of null但在render()方法它被识别并记录输入的结果。

因此我试图在deleteTodo功能道具绑定在TodoItemComponent

  <button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo.bind(this.props.todo)}> 
       <span className="fa fa-trash-o"></span> 
      </button> 

因此函数是这样的:

deleteTodo(todo){ 
     console.log('deleteTodo', todo); 
     this.props.onDelete(this.props.todo); 
    } 

有人能帮助我在这个问题上?

+0

你试过'onDelete = {()=> this.delete(1)}'或其他一些指标? – Li357

+0

你不能在'delete'方法内访问'this.props.todo'的值。所以,你必须为它提供一个上下文,像这样'onClick = {this.delete.bind(this,this.props.todo)}'。有了这个,你可以在'delete'自定义方法中访问待办事项。 – Rowland

+0

您不应该将呈现的React组件存储在状态中。将普通的旧JavaScript对象和数组保存在状态中,并且只在'render'中渲染React组件。 'addTodo'方法会导致渲染的组件被推入到一个在'render'生命周期之外更新的数组中。 –

回答

2

你的问题是Function.prototype.bind这里的滥用:

onClick={this.deleteTodo.bind(this.props.todo)} 
//       ^you're binding todo as the context 

第一个参数应该是绑定功能的情况下,即this,不待办事项。

onClick={this.deleteTodo.bind(this)} 

而且你应该使用deleteTodo函数中this.props.todo(现在有一个适当的范围内)。

或者,您可以an arrow function(即保持它的外上下文)传递todo

onClick={() => this.deleteTodo(this.props.todo)} 

和你deleteTodo方法会收到todo作为第一个参数。在this.state

+0

感谢您的完美,现在我在两个组件中记录道具。但是,当我尝试更新AddTodoComponent中的状态时,它会引发此错误: '未捕获的TypeError:无法读取未定义的属性'todoArray' – Sreinieren

+0

在每个其他函数中,this.state.todoArray被识别,除了delete )'比它甚至无法记录状态.. – Sreinieren

1

存储数据,只有创造反应的元素在render,类似如下:

class AddTodoComponent extends Component { 
    constructor(props) { 
     super(props); 

     this.state = { 
      todo: '', 
      todoArray: [] 
     }; 
    } 

    addTodo(e){ 
     this.state.todoArray.push(e.target.value); 
     this.setState({ todo: '' }); 
    } 

    delete(index){ 
     console.log('testDelete', this.state.todoArray); 
    } 

    handleChange(e){ 
     this.setState({ todo: e.target.value }); 
    } 

    render() { 
     return (   
      <div> 
       <div className="input-group m-b-md"> 
        <input type="text" className="form-control add-todo" placeholder="Todo..." value={this.state.todo} onChange={this.handleChange.bind(this)} /> 
        <span className="input-group-btn"> 
         <button className="btn btn-react" type="button" onClick={this.addTodo.bind(this)}>Add</button> 
        </span> 
       </div> 
       <ul className="list-group"> 
        {this.state.todoArray.map((todo, index) => (
         <TodoItemComponent todo={todo} onDelete={this.delete.bind(this, index)}></TodoItemComponent> 
        ))} 
       </ul> 
      </div> 
     ); 
    } 
} 
+0

感谢您的答案,但待办事项道具无法正确显示,即输入字段的值。 – Sreinieren

+0

只有触发'onChange'方法时才显示。 – Sreinieren

+0

我不太明白你想要它做什么。 –

相关问题