2016-09-22 99 views
0

我對React非常新穎(所以這可能非常簡單),並試圖在一個簡單的應用程序上嘗試時,我試圖從一個子組件中更改父組件的狀態時卡住了。從小孩修改父組件狀態

要讓應用程序工作,父組件必須保持狀態,然後傳遞給其他組件。因此,我創建了一個狀態變化函數,並將其傳遞給孩子。請參見下面的代碼:

JS:

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     status: [ 
     { 
      id: 1, 
      name: 'Item 1', 
      selected: false 
     }, { 
      id: 2, 
      name: 'Item 2', 
      selected: false 
     }] 
    } 
    } 

    addItem(name) { 
    let id = this.props.status.length + 1; 
    let newItem = this.props.status; 
    newItem.push({id, name, selected: true}); 
    this.setState({ 
     status: newItem 
    }); 
    } 

    render() { 
    return (
     <div><ItemList status={this.state.status} addItem={this.addItem} /></div> 
    ); 
    } 
} 

class ItemList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     search:'', 
    }; 
    } 

    handleAddSubmit(event) { 
    event.preventDefault(); 
    let name = this.refs.newit.value; 
    this.props.addItem(name); 
    this.refs.newit.value=''; 
    } 

    updateSearch(event) { 
    this.setState({search: event.target.value}); 
    } 

    render() { 
    let filteredItems = this.props.status.filter((item)=> { 
     return item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1; 
    }); 
    return (
    <div> 
     <div> 
      <input placeholder="Search" type="text" 
      value={this.state.search} 
      onChange={this.updateSearch.bind(this)}/> 
     </div> 
     <div> 
      {filteredItems.map((item) => { 
      return (<button id={item.id}>{item.name}</button> 
      ); 
      })} 
      <form onSubmit={this.handleAddSubmit.bind(this)}> 
      <input type="text" placeholder="enter your item" ref="newit"/> 
      </form> 
     </div> 
     </div> 
    ); 
    } 
} 


ReactDOM.render(<App/>, document.getElementById('app')); 

HTML:

<div id="app"></div> 

我知道如何代碼是錯誤的,如addItem功能無法訪問的狀態,但我不知道怎麼樣要解決這個問題。我試圖將父類的狀態從父類傳遞給子類,然後作爲addItem的變量備份,但這也不起作用(請參閱下面的代碼)。另外,我玩過.bind(this)和.bind(null),但沒有成功(我沒有真正理解React auto和這個綁定之間的區別)。

addItem(oldStatus, name) { 
    let id = oldStatus.length + 1; 
    let newItem = oldStatus; 
    newItem.push({id, name, selected: true}); 
    this.setState({ 
     status: newItem 
    }); 
    } 

我不知道如果我試圖做一些事情,這只是不可能的,不可取的,或者如果它只是一個簡單的錯誤。我在這裏查了很多問題和官方教程,但他們只是使用傳遞給函數的參數setState而不是嘗試訪問狀態(在我的情況下計算id)。我也研究了各種教程,因爲我相信這是基本概念,但還沒有找到解決方案。

謝謝你的幫助。

最佳,

中號

編輯:我創建了一個與的jsfiddle代碼:https://jsfiddle.net/magp/cw8h2pzk/4/

回答

2

可以打開控制檯查看錯誤。

一個錯誤是關於不綁定你的addItem和.bind(this)。

您應該將其綁定到您傳遞的方法。他們可能會在dom或其他組件中調用,所以這種情況會發生變化。但是,如果在傳遞過程中綁定這個,則上下文將是組件。您的this.state ...語句將按預期工作。

另一個錯誤是每個孩子都應該有一個唯一的關鍵。

這意味着如果你映射一個數組或者簡單地迭代數據並返回jsx,那麼你返回的每個jsx都應該有一個唯一的鍵。

這是工作jsfiddle。我有更改的字段如下。

<form onSubmit={this.handleAddSubmit.bind(this)}> 

{filteredItems.map((item) => { 
    return (<button id={item.id} key={item.id}>{item.name}</button); 
})} 

https://jsfiddle.net/8v2cu95x/1/

+1

感謝您的快速和全面的答覆。這幫助我理解了兩件事:1)我想要做的是有意而不是反模式,2)我不明白綁定是如何工作的。如果任何人都能指出詳細解釋這一點的資源,我會非常感激。大多數教程似乎忽略了對此的深入解釋。再次感謝 – mgp