简体   繁体   中英

ReactJS componentDidMount does not behave as expected with Bootstrap

I want to call $(dom).popover() on a rendered DOM. So I have:

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

This returns error: TypeError: $(...).popover is not a function . BUT if I put a delay in the componentDidMount , then it works, ie:

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

How can I accomplish the same thing without using setTimeout ?

Try placing your jquery code inside a $(document).ready().

EG :

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

Edit #1: In response to comment: "You should also explain why" – Rohit Gupta

If you ask why too much, it will destroy the wonder of it all.

I joke. I came across the answer because I was having the same problem as the OP. I was using jQuery to reinitialize a Materialize.css accordion widget(which uses jQuery) in my componentDidMount function--or at least I was trying. But it wasn't working like I figured it should.

Then I came here, saw the OP had tried using setTImeout, and it worked; I tried it; it worked for me--even at 1ms--then I had the idea that slapping in a document(ready) function might work since basically it does something similar to the componentDidMount lifecycle function. $(document).ready listens for the entire document to load before it runs anything in the callback--compondentDidMount listens for the component to mount before it runs anything.

When you put a $(document).ready function inside the componentDidMount function(and put all the stuff into the former that which would typically only be in the latter), it will delay the code in the componentDidMount function until the whole document is loaded rather than just the component that the componentDidMount function resides in. The popover function acts on some element of the page that has yet to load. With the OP's original code you can manually call the popover event in the console after the page has loaded, which will then initialize the effect, which implies that the element that is needed for the popover does not exist when componentDidMount is called, but does exist after the page is fully loaded--which is why $(document).ready works: that is when its callback is triggered.

That is my theory atleast :) Any alternative theories of why it works?

如果您在代码中定义了导入文字,请尝试删除。

// import * as $ from "jquery";

Make sure you have correctly included your js files like this:

<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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM