2016-03-04 152 views
0

我有一個包含3個組件的應用程序。 第一個是App.jsx 如下它調用TodoList的組分:reactjs從父母編輯孩子狀態

<TodoList items={this.state.items} loaded={this.state.loaded} /> 

的TodoList的組件呈現多個TodoListItem部件

module.exports = React.createClass({ 
render: function(){ 
    return (
    <ul> 
    {this.renderList()} 
    </ul> 
) 
}, 
renderList: function(){ 
    var children = []; 
    for(var key in this.props.items) { 
     if(this.props.items[key].text){ 
     var listItem = this.props.items[key]; 
     listItem.key = key; 
     children.push(
      <TodoListItem item={listItem} key={key} onEdit={this.handleItemEdit} /> 
     ) 
     } 
    } 
    return children; 
}, 
handleItemEdit: function(component){ 
    console.log(component); 
} 
}); 
在我TodolistItem部件IM

然後渲染多個li元素

module.exports = React.createClass({ 
getInitialState: function(){ 
    return { 
    text: this.props.item.text, 
    done: this.props.item.done 
    } 
}, 
render: function(){ 
    return (
    <li onClick="this.props.onEdit.bind(null,this)">{this.state.text}</li> 
) 
}, 

}); 

當我點擊李在父元素函數上的函數handlItemEdit被激發,我的問題是我可以如何改變其父母的handleItemEdit函數中的子元素的文本值? 什麼即時試圖做的是,當你點擊一個李開一個引導模式與輸入字段中,更改其文本,保存和通過新的道具TodoListItem

回答

0

TodoList組件,你應該寫getInitialState並保存道具物品國家,那麼在渲染從狀態(而不是從道具像你這樣)通項目TodoListItem組件:

for(var key in this.state.items) { 
    if(this.state.items[key].text){ 
    var listItem = this.state.items[key]; 
    listItem.key = key; 
    children.push(
     <TodoListItem item={listItem} key={key} onEdit={this.handleItemEdit} /> 
    ) 
    } 
} 

如果調用setStatehandleItemEdit方法中,render()將會看到更新的狀態,會被執行。 在這種情況下,所有你需要做的是改變狀態在你handleItemEdit,這將被傳遞到TodolistItem,你應該使用props,不state中呈現,就像這樣:

render: function(){ 
    return (
    <li onClick="this.props.onEdit.bind(null,this.props)">{this.props.text}</li> 
) 
}, 

通知你逝去的道具onEdit,所以你必須CHANE handleItemEdit是這樣的:在ECMAScript中6語法您的問題

handleItemEdit: function(itemProps){ 
    console.log('You clicked: ' + this.props.items[itemProps.key]); 
} 
+0

非常感謝您的回答!因爲todoList中的道具來自我添加的http請求 componentWillReceiveProps:function(){ this.setState({items:this.props.items}); } 現在在handleItemEdit我怎麼只能編輯點擊li的值? 我可以通過它的關鍵嗎? –

+0

'handleItemEdit'實際上應該在TodolistItem組件中,而不是在TodoList組件中......這會解決你的問題 –

+0

你也可以閱讀這篇[文章](https://facebook.github.io/react/tips/communicate-between- components.html),來介紹如何處理通信的beetwen組件,以另一種方式解決您的問題(如您想要的那樣) –

0

我已經測試解決方案。在你的符號中使用這個解決方案也很容易。基本上,你必須做的是從父母到孩子通過this,然後在你將onClick事件綁定到父母時使用它(因此你可以在事件處理函數中使用this)作爲secound參數,你通過props的孩子,其中key道具將指出非常醜陋的元素。然後,很容易挖掘父母的狀態,這將觸發父母的呈現,並級聯呈現新的(由用戶更改的)道具。

TodoList.js

class TodoList extends Component { 
    render(){ 
     return (
      <ul> 
       {this.props.items.map(function(listItem, key) { 
        return (listItem.text && 
         <TodoListItem item={listItem} todoList={this} key={key} onEdit={this.handleItemEdit}/> 
        ); 
       })} 
      </ul> 
     ) 
    }; 

    handleItemEdit(itemProps){ 
     console.log('You clicked: ' + this.props.items[itemProps.key].text); 
    }; 
} 

export default TodoList; 

TodoListItem.js

import React, { Component } from 'react'; 

class TodoListItem extends Component { 
    render() { 
     return (
      <li onClick={this.props.onEdit.bind(this.props.todoList, this.props.item)}>{this.props.item.text}</li> 
     ) 
    } 
} 

export default TodoListItem; 

我已經測試過它,它打印您點擊控制檯非常文本。這意味着oyu可以訪問這個TodoListItem,你可以在TodoList組件中改變它的狀態。