2017-07-24 25 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

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

相關問題