2015-04-16 65 views
4

我想在渲染的DOM上調用$(dom).popover()。所以我有:ReactJS componentDidMount的行爲與Bootstrap沒有預期的相同

module.exports = React.createClass({ 
    componentDidMount: function() { 
     $(this.getDOMNode()).popover(); 
    }, 
    render: function() { 
     return (// My DOM); 
    } 
}) 

這將返回錯誤:TypeError: $(...).popover is not a function。但如果我把一個延遲的componentDidMount,那麼它的工作原理,即:

componentDidMount: function() { 
    var _this = this; 
    setTimeout(function() { 
     $(_this.getDOMNode()).popover(); 
    }, 250); 
} 

我怎樣才能做到不使用setTimeout是一回事嗎?

+0

這似乎是'''在您試圖調用它時不會引用jQuery(因此不會返回jQuery對象),或者提供彈出窗口的插件尚未加載。 –

+0

不,'$'可以正常工作,它是無法找到的dom本身。所以'$(...)'是空的。 – Kousha

+2

$(...)'將永遠*返回一個jQuery對象。即使該集合是空的,「popover」方法也會存在。換句話說:'popover'方法的存在並不取決於集合的大小。你得到這個錯誤的事實表明還有其他問題。 –

回答

3

試着將你的jQuery代碼$(文件)。就緒()內。

E.G. :

componentDidMount: function() { 
var _this = this; 
$(document).ready(function() { 
    $(_this.getDOMNode()).popover(); 
}); 
} 

編輯#1:在響應評論:「你也應該解釋爲什麼」 - 羅特·古普塔

如果你問爲什麼太多,就會破壞這一切的奇蹟。

我開玩笑。我遇到了答案,因爲我遇到了和OP一樣的問題。我正在使用jQuery在我的componentDidMount函數中重新初始化Materialize.css手風琴小部件(它使用jQuery) - 或者至少我在嘗試。但它沒有像我想的那樣工作。

然後我來到這裏,看到OP已經嘗試過使用setTImeout,並且它工作了;我嘗試過這個;它爲我工作 - 即使在1ms - 然後我有這樣的想法,在文檔(就緒)功能可能會奏效,因爲它基本上做了類似於componentDidMount生命週期功能的東西。 $(document).ready在調用回調函數之前偵聽要加載的整個文檔 - compondentDidMount偵聽要運行的任何內容之前裝入的組件。

當你將一個$(document).ready函數放入componentDidMount函數中(並將所有東西放到前者中,通常只在後者中)時,它將延遲componentDidMount函數中的代碼,直到整個文檔將被加載,而不僅僅是componentDidMount函數所在的組件。彈出功能作用於尚未加載的頁面的某個元素。使用OP的原始代碼,您可以在加載頁面後在控制檯中手動調用popover事件,然後初始化該效果,這意味着在調用componentDidMount時,popover所需的元素不存在,但確實存在在頁面被完全加載之後 - 這就是爲什麼$(document).ready已經工作:這是當它的回調被觸發時。

這是我的理論atleast :)爲什麼它的作品的任何替代理論?

+0

你也應該解釋爲什麼 –

0

確保您正確包括您的js文件是這樣的:

<html> 
    <body> 
     ... 

     <script src="jquery.js"></script> 
     <script src="bootstrap.js"></script> 

     <!-- Your js file that starts React app --> 
     <script src="myapp.js"></script> 
    </body> 
</html> 
0

如果您在代碼中定義了導入文字,請嘗試刪除。

// import * as $ from "jquery"; 
相關問題