2017-06-21 258 views
1

我正在寫一個需要renderer屬性的React組件。通常,這是一個函數,它接受一個參數對象並返回另一個React組件。不過,我希望我的組件的用戶能夠傳入React組件類。然後,我會內部包裝該類的功能:如何判斷一個函數是否是一個類?

class MyComponent extends React.Component { 
    render() { 
     const { renderer } = this.props; 

     const renderFn = (renderer.isAComponentClass()) 
      ? (props => <renderer {...props} />) 
      : renderer; 

     return <div>{ renderFn(someArgs) }</div>; 
    } 
} 

當然,在JavaScript中,一個類也是一個功能。我如何檢查renderer是否爲班級?我使用Babel 6.

我知道我可以簡單地返回<renderer {...someArgs} />。如果我可以避免它,我寧願不這樣做,因爲這會不必要地膨脹組件樹。

+0

如果有人使用班級的Babel編譯版本會怎麼樣?那麼不管他們在那個時候都只是「功能」。你最好接受兩個獨立的參數。 – loganfsmyth

+0

無論哪種情況,它們都是函數(即'typeof thing ==='function'')。但是,這並不一定意味着無法區分它們。如果可證實無法實現,那麼這將是一個答案。 –

+0

好吧,如果'fn'是一個組件類,那麼'fn.prototype'應該包含基類組件方法,因此你可以測試它們的存在。如果它只是一個工廠函數,那麼'fn.prototype'將不包含組件方法。 – jfriend00

回答

1

可以使用正則表達式檢測本機類 - 只要它們不實現toString方法,該方法會將其表示形式更改爲字符串。

由於類與傳輸代碼中的函數沒有區別,因此無法檢測函數是否爲類。這是甚至不嘗試以編程方式區分它們的一個很好的理由。

它可以檢查是否React.Component是一個函數/類與

renderer.prototype instanceof React.Component 

祖先因爲這使不必要的限制,更好的選擇是將鴨子測試它,就像

renderer.prototype && ['render', 'setState', ...] 
    .map(methodName => typeof renderer.prototype[methodName]) 
    .every(methodType => methodType === 'function') 

但是,這些檢查都不準確。在某些情況下,財產可能會混亂,例如當一堂課被裝飾時。確定知道類是組件的唯一方法是首先實例化它。

而且,如果渲染器功能和組件永遠不會混淆,API會更乾淨,例如單獨的rendererrendererComponent屬性。

相關問題