簡體   English   中英

在React子組件上調用方法

[英]Call methods on React children components

我想編寫一個Form組件,可以導出一個方法來驗證其子代。 不幸的是,表格並沒有“看到”其子女的任何方法。

以下是我如何定義Form的潛在子級:

var Input = React.createClass({
  validate: function() {
    ...
  },
});

以下是我定義Form類的方法:

var Form = React.createClass({
  isValid: function() {
    var valid = true;
    this.props.children.forEach(function(component) {
      // --> This iterates over all children that I pass
      if (typeof component.validate === 'function') {
        // --> code never reaches this point
        component.validate();
        valid = valid && component.isValid();
      }
    });
    return valid;
  }
});

我注意到我可以使用refs調用子組件上的方法,但我不能通過props.children調用方法。

這個React行為有原因嗎?

我怎樣才能解決這個問題?

技術原因是,當您嘗試訪問子組件時,它們實際上還不存在(在DOM中)。 他們尚未安裝。 它們已作為構造函數prop或方法作為反應傳遞給<Form>組件。 (因此React.createClass()的名稱類)。

正如你所指出的,這可以通過使用refs來規避,但我不推薦它。 在許多情況下,refs往往是反應不適合的東西的捷徑,因此應該避免。

可能是設計反應使得父母很難/不可能獲得孩子的方法。 他們不應該這樣做。 孩子的方法應該在孩子身上,如果他們是孩子的私人方式:他們在孩子內部做一些事情,不應該直接向父母傳達。 如果是這種情況,那么應該在父母內部進行處理。 因為父母至少擁有孩子擁有的所有信息和數據。

現在在你的情況下,我想每個輸入(子)組件都有某種特定的驗證方法,它檢查輸入值,並根據結果,做一些錯誤信息反饋。 讓我們說一個不正確的字段周圍的紅色輪廓。

在反應方式中,這可以通過以下方式實現:

  • <Form>組件具有state,其中包含runValidation boolean。
  • 只要runValidationsetState( { runValidation: true });內設置為true setState( { runValidation: true }); 反應會自動重新呈現所有孩子。
  • 如果將runValidation包含為所有子項的prop。
  • 那么每個孩子都可以使用if (this.props.runValidation) { this.validate() }類的東西來檢查他們的render()函數。
  • 這將執行子進程中的validate()函數
  • validate函數甚至可以使用子狀態(當新道具進入時狀態不會改變),並將其用於驗證消息(例如'請在密碼中添加更復雜的符號')

現在還沒有解決的問題是,您可能希望在所有孩子都自己驗證后在表單級別進行一些檢查:例如,當所有孩子都可以時,請提交表單。

要解決這個問題,您可以將refs快捷方式應用於最終檢查並提交。 並在componentDidUpdate()函數內的<Form>實現一個方法,以檢查每個孩子是否正常(例如,有綠色邊框)和是否單擊了提交,然后提交。 但作為一般規則,我強烈建議不要使用引用。

對於最終表單驗證,更好的方法是:

  • <Form>添加一個非狀態變量,該變量為每個孩子保留布爾值。 注意,它必須是非狀態的,以防止兒童觸發新的渲染周期。
  • validateForm函數作為(回調)道具傳遞給每個子項。
  • 在每個子this.props.validateForm(someChildID) validate()內,調用this.props.validateForm(someChildID) ,它更新Form中變量的相應布爾值。
  • 在表單中的validateForm函數的末尾,檢查所有布爾值是否為真,如果是,則提交表單(或更改表單狀態或其他)。

對於一個更長的(並且更復雜的)解決方案來形成反應中的驗證(使用flux),您可以查看本文

我不確定我是否遺漏了什么,但是在嘗試@wintvelt建議我在React的render方法中調用runValidation方法時遇到問題,因為在我的情況下runValidation通過調用setState來改變狀態因此觸發渲染方法顯然是一種不好的做法,因為渲染方法必須是純粹的,如果我把runValidation放在willReceiveProps ,它將不會第一次被調用,因為if條件不是真的(這個條件在使用setState的父組件,但在第一次調用willReceiveProps它仍然是假的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM