2016-04-30 43 views
0

我想寫一個TODO列表與反應,但是當我改變一個TodoItem的check屬性,我得到了相反的結果。defaultChecked也沒用。爲什麼React改變我檢查過的道具?

 var Todo = React.createClass({ 
     getInitialState(){ 
     return{i:0,data:[],allCompleted:false}; 
     }, 
     handleKeyPress(e){ 
     if(e.key === 'Enter' && e.currentTarget.value != ''){ 
      localStorage.setItem(uuid(e.currentTarget.value),JSON.stringify({uuid:uuid(e.currentTarget.value),checked:false,todoContent:e.currentTarget.value})); 
      this.state.data.push({uuid:uuid(e.currentTarget.value),checked:false,todoContent:e.currentTarget.value}); 
      this.setState({i: ++(this.state.i),data:this.state.data}, 
      ()=>{e.target.value = ''}); 

     } 
     }, 
     /* 
     *↓Here I made every item.checked = true when I click the all-completed checkbox; 
     */ 
     handleAllComplete(e){ 
     if(!this.state.allCompleted){ 
      this.state.allCompleted = true; 
      this.state.data.map((item)=>{item.checked?true:item.checked = !item.checked}); 
      return this.setState({data:this.state.data}); 
     } 
     this.state.allCompleted = false; 
     this.state.data.map((item)=>{item.checked = false}); 
     return this.setState({data:this.state.data}); 

     }, 
     handleOneComplete(todoUuid){ 
     console.log('one completed');  
     this.state.data.map((item)=>{item.uuid==todoUuid?(item.checked = !item.checked):undefined;}); 
     this.setState({data:this.state.data}); 
     }, 
     componentWillMount(){ 
     let data = []; 
     for(var i in localStorage){ 
      if(localStorage.hasOwnProperty(i)){ 
      data.push(JSON.parse(localStorage.getItem(i))); 
      } 
     } 
     this.setState({i:i,data:data}); 
     }, 
     render(){ 
     console.log(this.state.data); 
     return <div> 
      <AddTodoItem handleKeyPress={this.handleKeyPress} handleAllComplete={this.handleAllComplete}/> 
      <TodoItemContainer data={this.state.data} handleOneComplete={this.handleOneComplete}/> 
      <TodoToolBar /> 
     </div> 
     } 
    }); 

     var TodoItemContainer = React.createClass({ 
     render(){ 
     var todoItems = []; 
     for(let i of this.props.data){ 

      todoItems.push(<TodoItem key={i.uuid} uuid={i.uuid} checked={i.checked} content={i.todoContent} style={i.checked?{color:'red'}:undefined} handleOneComplete={this.props.handleOneComplete}/>); 
      console.log(i.checked,'in container'); 
      /* 
      *↑Here's I got the check attribute is true and it meets my expectations; 
      */ 
     } 
     if(todoItems.toString() == ''){ 
      return <div></div>; 
     } 

     return <div>{todoItems}</div>; 

     } 
    }) 

     var TodoItem = React.createClass({ 
     getInitialState(){ 
     return ({checked:this.props.checked,todoContent:this.props.content}); 
     }, 
     componentWillReceiveProps(){ 
     /* 
     *but Here, i got checked = false and that's my question; 
     */ 
     console.log(this.props.checked,'will receive'); 
     this.setState({checked:this.props.checked,todoContent:this.props.content}); 
     }, 
     render(){ 
     console.log(this.state.checked,'render item'); 
     return <div> 
      <input type="checkbox" defaultChecked={this.state.checked} onChange={this.props.handleOneComplete.bind(null,this.props.uuid)}/> 
      <lable style={this.props.style}>{this.state.todoContent}</lable> 
      <button>delete</button> 
     </div> 
     }, 
    }); 

簡單地說,我設置每TodoItem checked = true,但內TodoItemthis.props.checkedfalse

https://jsfiddle.net/20xads1n/1/

+0

你可以上傳代碼到jsfiddle,用'react-dom','渲染'你的組件到dom(然後,這裏的人可以進一步看)?檢查了你的代碼,也感到困惑。 –

+0

@DavidGuan感謝您的建議,我上傳了:) – ReactNewbee

回答

0

這裏就是你們的榜樣 https://jsfiddle.net/7s99f2aj/的固定版本。 有2個問題:

1)您在componentWillReceiveProps方法錯過nextProps參數(見https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops) 2)我在你的TodoItem組件更改defaultCheckedchecked

而且我想推薦你使用setState到處都是當你改變你的狀態(即this.setState({allCompleted: true})而不是this.state.allCompleted = true;)而不是直接在map這樣的函數中改變狀態:this.state.data.map((item)=>{item.checked?true:item.checked = !item.checked});。相反,請考慮創建全新的data對象,並使用setState更改您的狀態。

相關問題