2016-01-14 39 views
0

所以我讀過,我們應該儘量避免裁判訪問子組件陣營:一種避免參考文獻訪問子組件的狀態

React refs with components

https://facebook.github.io/react/docs/more-about-refs.html

在當我的情況,但是,我想不到在我的情況下避免這種情況的方法。


場景:

我有包含TagInput子組件,它類似於Stackoveflow的 「標籤」 輸入欄MyForm的父組件。當用戶輸入一個輸入+空格時,標籤被添加到TagInput的內部狀態。當用戶提交表單時,所選標籤列表會發布到我的服務器上。


實現:

var MyForm = React.createClass({ 
    submit: function() { 
     var selectedTags = this.refs.tagInput.state.selectedTags; 

     $.post(
      SERVER_URL, 
      data: { tags: selectedTags } 
     ); 
    }, 

    render: function() { 
     return (
      <form onSubmit={this.submit}> 
       <TagInput ref="tagInput"> 
      </form> 
     ); 
    } 
}); 


var TagInput = React.createClass({ 
    getInitialState: function() { 
     return { 
      selectedTags: [] 
     } 
    }, 

    // This is called when the user types SPACE in input field 
    handleAddTag: function(tag) { 
     this.setState({ 
      selectedTags: this.state.selectedTags.concat(tag); 
     }); 
    }, 

    render: function() { 
     return (
      <form> 
       <ul>{this.state.selectedTags}</ul> 
       <input type="text" /> 
      </form> 
     ); 
    } 
}); 


上面的代碼工作正常,並做什麼的預期。唯一值得關注的是我使用ref來直接訪問子組件的內部狀態,我不確定這是否是正確的「React」方式。

我想一個選項是維持MyForm的,而不是TagInput的「selectedTags」狀態。這並沒有真正意義在我的情況,因爲在現實中我的表單包含5個TagInput組件和許多其他國家來管理..

誰能想到,以提高我設計的方法嗎?或者在我的情況下使用refs是不可避免的?

感謝

回答

2

您可以從父組件傳遞handleAddTag到孩子,並保持所選擇的標籤的狀態在表單組件。現在,當您提交表單時,您將從表單上的狀態中拉出而不是使用引用。

var MyForm = React.createClass({ 
    getInitialState: function() { 
     return { 
      selectedTags: [] 
     } 
    }, 

    submit: function() { 
     var selectedTags = this.state.selectedTags; 

     $.post(
      SERVER_URL, 
      data: { tags: selectedTags } 
     ); 
    }, 

    // This is called when the user types SPACE in input field 
    handleAddTag: function(tag) { 
     this.setState({ 
      selectedTags: this.state.selectedTags.concat(tag); 
     }); 
    }, 

    render: function() { 
     return (
      <form onSubmit={this.submit}> 
       <TagInput handleAddTag={this.handleAddTag} ref="tagInput"> 
      </form> 
     ); 
    } 
}); 

//Use this.props.handleAddTag() to update state in Form Component 
var TagInput = React.createClass({ 

    render: function() { 
     return (
      <form> 
       <ul>{this.state.selectedTags}</ul> 
       <input type="text" /> 
      </form> 
     ); 
    } 
}); 

我發現,用裁判來獲得某些數據不如使用裁判進行修改,這是非常糟糕的用戶界面,因爲它會導致UI不與您所在州或您的應用程序內嵌的那樣糟糕。