2017-11-21 10 views
0

私は、リストから項目を削除する機能を除いて、正常に動作しているアプリを簡単に持っています。私はすでに各リスト項目にボタンを追加しています。 .filter()メソッドを使用して状態を渡すことがわかっていますが、これは削除されたToDoを持たない新しい配列ですが、このようなことをする方法がわかりません。ここでリストに反応すると、この削除ボタンはどのように機能しますか?

は、Appの主成分である:ここでは、その後

class App extends Component { 
    constructor(props){ 
    super(props); 
    this.state = { 
     todos: [ 
     { description: 'Walk the cat', isCompleted: true }, 
     { description: 'Throw the dishes away', isCompleted: false }, 
     { description: 'Buy new dishes', isCompleted: false } 
     ], 
     newTodoDescription: '' 
    }; 
    } 

    deleteTodo(e) { 
    this.setState({ }) 
    } 

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

    handleSubmit(e) { 
    e.preventDefault(); 
    if (!this.state.newTodoDescription) { return } 
    const newTodo = { description: this.state.newTodoDescription, 
    isCompleted: false }; 
    this.setState({ todos: [...this.state.todos, newTodo], 
    newTodoDescription: '' }); 
    } 

    toggleComplete(index) { 
    const todos = this.state.todos.slice(); 
    const todo = todos[index]; 
    todo.isCompleted = todo.isCompleted ? false : true; 
    this.setState({ todos: todos }); 
    } 

    render() { 
    return (
     <div className="App"> 
     <ul> 
      { this.state.todos.map((todo, index) => 
      <ToDo key={ index } description={ todo.description } 
       isCompleted={ todo.isCompleted } toggleComplete={() => 
       this.toggleComplete(index) } /> 
     )} 
     </ul> 
     <form onSubmit={ (e) => this.handleSubmit(e) }> 
      <input type="text" value={ this.state.newTodoDescription } 
      onChange={ (e) => this.handleChange(e) } /> 
      <input type="submit" /> 
     </form> 

     </div> 
    ); 
    } 
} 

とのto-doのコンポーネントです:

class ToDo extends Component { 
    render() { 
    return (
     <li> 
     <input type="checkbox" checked={ this.props.isCompleted } 
      onChange={ this.props.toggleComplete } /> 
     <button>Destroy!</button> 
     <span>{ this.props.description }</span> 
     </li> 
    ); 
    } 
} 

答えて

0

Event handlers:あなたは、各ToDoonDelete小道具を送信することができます

const Todo = ({ description, id, isCompleted, toggleComplete, onDelete }) => 
    <li> 
    <input 
     type="checkbox" 
     checked={isCompleted} 
     onChange={toggleComplete} 
    /> 
    <button onClick={() => onDelete(id)}>Destroy!</button> 
    <span>{description}</span> 
    </li> 

そしてAppからの:

<ToDo 
    // other props here 
    onDelete={this.deleteTodo} 
/> 

@Dakotaが指摘しているように、リストをマッピングする際にインデックスとしてキーを使用するのは良いパターンではありません。

たぶん自分initialStateを変更し、それらの一つ一つにidを設定します。

this.state = { 
    todos: [ 
    { id: 1, description: 'Walk the cat', isCompleted: true }, 
    { id: 2, description: 'Throw the dishes away', isCompleted: false }, 
    { id: 3, description: 'Buy new dishes', isCompleted: false } 
    ], 
    newTodoDescription: '', 
} 

は、これはまた、配列から項目を削除する人生が容易になります:

deleteTodo(id) { 
    this.setState((prevState) => ({ 
    items: prevState.items.filter(item => item.id !== id), 
    })) 
} 
+0

これは理にかなっているが、 const Todo =({description、id、isCompleted、toggleComplete、onDelete})=> – Db12797

+0

@ Db12797私は 'ToDo'をステートレスコンポーネントとして書きました。あなたのバベル構成をチェックするか、あなたが書いたように「ToDo」を保つことができます。 'id'と' onDelete'の小道具を加えればいいはずです:) – mersocarlin

0

あなたが任意のさらなる入る前に、あなたがキーとしてリストインデックスを使用しないでくださいあなたの反応要素のために。 ToDoにIDを与え、それをキーとして使用します。時々あなたはこれで逃げることができますが、あなたが物事を削除しているときにはほとんど常に問題を引き起こします。

https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

あなたは私に説明してみましょう。この

を知っているだけで、記事を読みたくない場合は、キーが唯一のものであるDOM 要素を識別するために使用し反応します。アイテムをリストにプッシュするか、中間に何か を削除するとどうなりますか?キーが以前と同じである場合Reactは とみなし、DOM要素は以前と同じコンポーネントを表します。しかし、 はもはや真です。

別の注意点として、あなたのボタンにonClickを追加し、アプリケーションからプロップとして実行する機能を渡します。

<button onClick={() => this.props.handleClick(this.props.id)} /> 

と救助にApp.js

... 

constructor(props) { 
    ... 
    this.handleClick = this.handleClick.bind(this); 
} 

handleClick(id) { 
    // Do stuff 
} 

<ToDo 
    ... 
    handleClick={this.handleClick} 
/> 
関連する問題