2017-04-18 40 views
1

因此,我有一個帶有複選框的項目列表,就像經典的待辦事項應用程序一樣。React複選框即使在卸載組件後也會檢查

enter image description here

當我選擇「約翰尼」,然後單擊「刪除選定的記錄,」約翰尼不會消失。好極了!

enter image description here

但是,一旦約翰尼走了蕾妮被選中,現在。

enter image description here

我沒點擊蕾妮。我只點擊約翰尼,但一旦約翰尼被刪除,蕾妮就被檢查了。跆拳道?

很明顯,在複選框DOM保持真正的檢查狀態時發生了一些事情,即使我剛剛刪除了複選框。

我試圖通過更新componentWillUnmount中的狀態來解決這個問題,但那並不奏效。

import React, {Component} from 'react'; 

class Person extends Component { 

    constructor(props) { 
    super(props); 

    this.state = { 
     checked: false 
    } 

    this.checkboxToggle = this.checkboxToggle.bind(this); 
    } 

    checkboxToggle() { 
    this.setState({ checked: !this.state.checked },() => { 
     if (this.state.checked === false) { 
     console.log("Checked should be FALSE"); 
     } 
     else if (this.state.checked === true) { 
     console.log("Checked should be TRUE"); 
     this.props.setForDelete(this.props.person._id); 
     } 
    }); 
    } 

    componentWillUnmount() { 
    this.setState({ checked: false }); 
    } 

    render() { 
     return (
      <div> 
      <input type="checkbox" name="person" checked={this.state.checked} onChange={this.checkboxToggle} /> 
      {this.props.person.name} ({this.props.person.age}) 
      </div> 
     ); 
    } 
} 

export default Person; 

Person組件中的其他部分工作正常。我刪除了任何記錄後,如何取消所有複選框的選擇?

更新:這裏是PeopleList,它是持有所有人員的組件。

import React, { Component } from 'react'; 
import Person from './Person'; 

class PeopleList extends Component { 

    constructor(props) { 
    super(props); 
    } 

    componentWillUnmount() { 
    this.props.resetSetForDeleteArr(); 
    } 

    render() { 
    return(
     <div> 
     {this.props.people.map((person, i) => { 
      return <Person key={i} person={person} setForDelete={this.props.setForDelete} />; 
     })} 
     <div onClick={() => this.props.deleteRecords()}>Delete Selected Records</div> 
     <div onClick={() => this.props.resetSetForDeleteArr()}>Empty Array.</div> 
     </div> 
    ); 
    } 

} // end class 

export default PeopleList; 
+0

你能告訴其中personlist被渲染組件的代碼? – Chris

+0

@Chris剛剛更新。 –

回答

5

不要使用數組索引作爲關鍵屬性!

關鍵是React用來識別DOM元素的唯一道具。如果密鑰與以前一樣,就您的情況而言0 React假定DOM元素表示與以前相同的內容 - 即使現在有另一個文本。

So React會不是重新顯示狀態並更新選中的屬性。

使用一些獨特的,而不是像:

<Person key={person + '_' + i} ... 
2

嘗試改變下面一行放在PeopleList

{this.props.people.map((person, i) => { 
     return <Person key={person._id} person={person} setForDelete={this.props.setForDelete} />; 
    })} 
3

我想你可能有一些問題,狀態和傳承的功能。我創建了一個反映當前實現的示例,它使用簡單的映射和過濾函數來模擬刪除。如果我必須猜測你可能沒有跟蹤哪些數據被檢查和刪除,並且可能檢查值被緩存。正如你可以在代碼中看到波紋管這裏有一對夫婦,你可以實現使代碼更容易的建議:

  • 請別人爲阿呆/葉組件,畢竟它只是呈現 你的複選框,不要試圖在那裏保持檢查狀態。(至少 刪除卸載生命週期通常你不需要它)
  • 你可以使用context或者一個庫,可以幫助你跟蹤狀態,mobx是相當簡單的實現。
  • onClick={() => this.props.deleteRecords()}>可能看起來好像這樣onClick={this.props.deleteRecords.bind(this)}>如果您不需要人員列表中的任何額外邏輯。

到這裏看看,並嘗試運行它:

import React, {Component} from 'react'; 
import {render} from 'react-dom'; 

const Person = ({person, setForDelete}) => (
      <div> 
      <input type="checkbox" name="person" checked={person.checked} onChange={setForDelete.bind(this, person)} /> 
      {person.name} 
      </div> 
); 


class PeopleList extends Component { 

    render() { 

    return(
     <div> 
     {this.props.people.map((person, i) => { 
     return <Person key={i} person={person} setForDelete={this.props.setForDelete} />; 
     })} 
     <div onClick={this.props.deleteRecords}>Delete Selected Records</div> 
    </div> 
    ); 
    } 

} // end class 

class App extends React.Component { 

    constructor(props) { 
    super(props) 
    this.state = {people:[{id:1, name:'Cesar', checked:false},{id:2, name:'Jose', checked:false},{id:3, name:'Marbel', checked:false}]} 
    } 

    deleteRecords() { 
    const people = this.state.people.filter(p => !p.checked); 

    this.setState({people}); 
} 

    setForDelete(person) { 
    const checked = !person.checked; 
    const people = this.state.people.map((p)=>{ 
     if(p.id === person.id) 
     return {name:person.name, checked}; 
     return p; 
    }); 

    this.setState({people}); 
    } 

    render() { 

    return <PeopleList people={this.state.people} deleteRecords={this.deleteRecords.bind(this)} setForDelete={this.setForDelete.bind(this)}/>; 
    } 
} 

render(<App/>, document.getElementById('app')); 
相關問題