簡體   English   中英

將 ref 傳遞給 prop 的正確方法是什么?

[英]What's the proper way of passing a ref to a prop?

我正在嘗試將一個組件的 ref 傳遞給另一個組件。 由於不推薦使用字符串引用,因此我使用回調引用。

所以我有類似的東西:

<One ref={c => this.one = c}/>
<Two one={this.one}/>

問題是,每當我試圖訪問this.props.one里面Two我得到undefined

我什至在Two上試過這個:

componentDidMount(){
    setTimeout(()=>{
        console.log(this.props.one);
    },5000)
}

似乎問題在於,當創建 prop 時,ref 還不存在,因為它是在安裝One創建的。 但我不知道如何“刷新” Two上的道具以獲取已安裝組件的引用。

那么將 ref 傳遞給另一個組件的正確方法是什么?

編輯

一些用戶建議將該邏輯封裝在更高的組件中,該組件本身呈現那些其他子組件。

這種方法的問題在於您無法創建可重用的邏輯,並且必須在這些封裝組件中一遍又一遍地重復相同的邏輯。

假設你想創建一個通用的<Form>組件,它封裝了你的商店的提交邏輯、錯誤檢查等。你做這樣的事情:

<Form>
    <Input/>
    <Input/>
    <Input/>
    <Input/>
    <SubmitButton/> 
</Form>

在這個例子中, <Form>不能訪問孩子的實例(和方法),因為this.props.children不返回這些實例。 它返回一些偽組件列表。

那么如何在不傳遞 ref 的情況下檢查某個<Input/>是否檢測到驗證錯誤?

您必須使用驗證邏輯將這些組件封裝在另一個組件中。 例如在<UserForm> 但是由於每個表單都不同,因此必須在<CategoryForm><GoupForm>等中復制相同的邏輯。這是非常低效的,這就是為什么我想將驗證邏輯封裝在<Form>並傳遞<Input>引用組件到<Form>

一般來說,“ref”特性是 React 中的一種反模式。 它的存在是為了支持副作用驅動的開發,但是為了從 React 編程方式中獲得最大收益,您應該盡可能避免“引用”。

至於你的特定問題,將一個孩子傳遞給它的兄弟姐妹是一個雞與蛋的場景。 ref 回調在孩子被掛載時觸發,而不是在渲染期間觸發,這就是您的示例不起作用的原因。 您可以嘗試的一件事是將 ref 推入狀態,然后從狀態讀取到另一個孩子。 所以:

<One ref={c => !this.state.one && this.setState({ one: c })}/>
<Two one={this.state.one}/>

注意:如果沒有!this.state.one這將導致無限循環。

這是此工作的 codepen 示例(查看控制台以查看記錄的兄弟參考): http : //codepen.io/anon/pen/pbqvRA

現在使用新的 ref api (自 React 16 起可用 - 感謝 perilandmishap 指出這一點)現在要簡單得多。

class MyComponent extends React.Component {
  constructor (props) {
    super(props);
    this.oneRef = React.createRef();
  }

  render () {
    return (
      <React.Fragment>
        <One ref={this.oneRef} />
        <Two one={this.oneRef} />
      </React.Fragment>
    }
  }
}

您將在Two使用道具,例如:

this.props.one.current

這種方法有幾點值得注意:

ref 將是一個具有current屬性的對象。 在安裝元素/組件之前,該屬性將為null 一旦掛載,它將是One的實例。 一旦<Two />被掛載,引用它應該是安全的。

一旦<One />實例被卸載,ref 上的current屬性將返回為null

一般來說,如果你需要傳遞一個在調用時可能沒有設置的引用,你可以傳遞一個 lambda:

<One ref={c => this.one = c}/>
<Two one={() => this.one}/>

然后將其引用為

this.props.one()

如果在您調用它時已設置它,您將獲得一個值。 在此之前,您會得到undefined (假設它沒有被初始化)。

值得注意的是,當它可用時,您不一定會重新渲染,我希望它在第一次渲染時undefined 這是使用 state 來保存您的參考確實可以處理的事情,但您不會獲得多次重新渲染。

鑒於這一切,我會建議任何代碼用的是裁判移動OneTwo成被渲染組件OneTwo ,避免一切與這兩個戰略,一個在@Carl斯維爾的答案的問題。

暫無
暫無

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

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