2015-11-30 67 views
22

訪問子組件函數React的文檔聲明父組件可以通過引用訪問組件函數。請參閱:https://facebook.github.io/react/tips/expose-component-functions.htmlReact ES6 |如何通過參考

我試圖在我的應用程序中使用它,但在調用子函數時遇到「未定義不是函數」錯誤。我想知道這與使用React類的ES6格式有什麼關係,因爲我沒有看到我的代碼和文檔之間有任何其他差異。

我有一個對話框組件,看起來像下面的僞代碼。對話框有一個調用save()的「Save」按鈕,它需要調用子內容組件中的save()函數。內容組件收集子窗體字段的信息並執行保存。

class MyDialog extends React.Component { 
    save() { 
    this.refs.content.save();     <-- save() is undefined 
    } 

    render() { 
    return (
     <Dialog action={this.save.bind(this)}> 
     <Content ref="content"/> 
     </Dialog>); 
    } 
} 

class Content extends React.Component { 
    save() { 
    // Get values from child fields 
    // and save the content 
    } 
} 

我可以改爲通過一個道具(saveOnNextUpdate)下降到內容,然後執行保存,只要它是真實的,但我寧願弄清楚如何獲得上述工作的陣營文檔中詳細描述的方法。

有關如何讓doc方法工作或以不同方式訪問子組件函數的任何想法?

+0

什麼版本的反應您使用的? – Tyrsius

+0

你的僞示例工作:https://jsfiddle.net/vbj34euk/所以它可能是另一個問題。你能發佈更多真實的代碼嗎? – m90

+0

用於包裝組件(與redux或其他插件連接的組件)。我們需要使用getWrappedInstance()來獲取包裝的實例,然後我們可以訪問該組件的狀態,引用和方法。這裏是解釋它的視頻 - https://youtu.be/VpdKjocgCtA – Prem

回答

-1

事實證明,m90是對的 - 這完全是一個不同的問題。如果有人在將來遇到同樣的問題,我會發布解決方案。

我的應用程序是使用Redux構建的,問題源於使用react-redux connect函數將組件連接到存儲/全局狀態。出於某種原因,導出組件並將其連接到存儲庫使其無法訪問其中的功能。爲了解決這個問題,我必須從內容中刪除所有使用全局狀態,以便我可以將它導出爲「啞」組件。

更清晰,Content.js是這樣的:

var connect = require('react-redux').connect; 

class Content extends React.Component { 
    save() { 
    // Get values from child fields 
    // and save the content 

    // Use of this.props.stateObject 
    } 
} 

function mapStateToProps(state) { 
    const { 
    stateObject 
    } = state; 

    return { 
    stateObject 
    }; 
} 

module.exports = connect(mapStateToProps)(Content); 

取出使用全局狀態(因此使用的連接和mapStateToProps的讓我導出組件使用:

module.exports = Content; 

訪問this.refs.content.save()這樣做後,神奇地奏效。

+1

您可能想要將此作爲問題添加到redux回購中。看起來像是可以修復的東西。 –

+0

這實際上是有道理的。 React-Redux的connect()函數創建一個新的包裝器組件,用於實際編寫自己的包裝器組件。包裝器組件沒有save()函數,所以這種方法是行不通的。 在這種情況下,您最好使用傳遞迴調方法。 – markerikson

+4

connect()函數確實有第三個參數的withRef標誌,這可能是解決您的問題的方法。儘管坦率地說父組件調用子組件的方法似乎相當反React。 –

39

Redux的連接接受一個選項parametre作爲第四參數。在這種運您可以將標誌withRef設置爲true。然後你可以通過使用getWrappedInstance()來訪問引用的函數。就像這樣:

class MyDialog extends React.Component { 
    save() { 
    this.refs.content.getWrappedInstance().save(); 
    } 

    render() { 
    return (
     <Dialog action={this.save.bind(this)}> 
     <Content ref="content"/> 
     </Dialog>); 
    } 
} 

class Content extends React.Component { 
    save() { ... } 
} 

function mapStateToProps(state) { ... } 

module.exports = connect(mapStateToProps, null, null, { withRef: true })(Content); 

瞭解更多關於在這裏:​​https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options

值得一讀這篇文章的使用裁判,並考慮是否有更好的方法:https://facebook.github.io/react/docs/refs-and-the-dom.html#dont-overuse-refs

+2

字符串ref已棄用 – InspiredJW

+1

如果可以的話,我會給予更多讚許。花費數小時尋找解決方案。這釘了它。 :) – Rob10e

+0

它的工作原理。謝謝 –

0

的另一種方式做這將是使用其他一些道具名稱(ref除外)。我發現,這也是行之有效的,如果你使用像styled-componentsemotion例如庫的連接MyComponent

<MyComponent 
    ... 
    innerRef={(node) => { this.myRef = node; }} 
/>