A
A
asakasinsky2017-09-20 18:42:58
JavaScript
asakasinsky, 2017-09-20 18:42:58

Why can getElementById() return null in production version of react app?

Why can getElementById() return null in production version of react application, while querySelector works correctly?
In a simple example, everything is ok. The external script is loaded, getElementById and querySelector return what you need:
https://codepen.io/asakasinsky/pen/MEydXg
But after building the react application, I encountered strange behavior:
getElementById started returning null.
There was an error, after checking which I found that null is passed to ReactDOM.render instead of the application container element

ReactDOM.render(
        <AppContainer errorReporter={Redbox}>
            <Root store={store} history={history}/>
        </AppContainer>,
        document.getElementById('app')
    );

To check at the very beginning of index.js, before imports, by calling the render() method, I posted the following code:
document.addEventListener('DOMContentLoaded', function () {
    console.log('loaded');
    console.log('querySelector after load', document.querySelector('#app'));
    console.log('getElementById after load', document.getElementById('app'));
});

console.log('querySelector', document.querySelector('#app'));
console.log('getElementById', document.getElementById('app'));

Console output:
2a74e6457ea640f7a8fcdccce386f861.png
As you can see, the behavior of getElementById does not depend on the DOMContentLoaded event.
The "Cannot read property 'sidebarIsOpen' of undefined" error occurs for exactly the same reason.
I'm thinking about this interesting problem, and I suspect that some of the libraries are to blame.
Can someone come across this?

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
asakasinsky, 2017-09-21
@asakasinsky

Everything turned out to be more prosaic. The reason was the gulp-rev-all plugin used in the builder. Below is a piece of code from the collector:

gulp.task('build:revAssets', ['css', 'moveAssets'], function () {
    var rev = $.revAll;
    return gulp.src('./public/assets/**/*')
        .pipe(rev.revision({
            fileNameManifest: 'manifest.json'
        }))
        .pipe(gulp.dest('./public/assets'))
        .pipe(rev.manifestFile())
        .pipe(gulp.dest('./public/assets'))
})

Now, the result of building the test file (the result is formatted for convenience):
! function(modules) {
    function __webpack_require__(moduleId) {
        if (installedModules[moduleId]) return installedModules[moduleId].exports;
        var module = installedModules[moduleId] = {
            i: moduleId,
            l: !1,
            exports: {}
        };
        return modules[moduleId].call(module.exports, module, module.exports, __webpack_require__), module.l = !0, module.exports
    }
    var installedModules = {};
    __webpack_require__.m = modules, __webpack_require__.c = installedModules, __webpack_require__.d = function(exports, name, getter) {
        __webpack_require__.o(exports, name) || Object.defineProperty(exports, name, {
            configurable: !1,
            enumerable: !0,
            get: getter
        })
    }, __webpack_require__.n = function(module) {
        var getter = module && module.__esModule ? function() {
            return module.default
        } : function() {
            return module
        };
        return __webpack_require__.d(getter, "a", getter), getter
    }, __webpack_require__.o = function(object, property) {
        return Object.prototype.hasOwnProperty.call(object, property)
    }, __webpack_require__.p = "/assets/", __webpack_require__(__webpack_require__.s = 0)
}


([function(module, exports, __webpack_require__) {
    module.exports = __webpack_require__(1)
}, function(module, exports, __webpack_require__) {
    "use strict";
    console.log("querySelector", document.querySelector("#app")), console.log("getElementById", document.getElementById("app.14b3524f"))
}]);

Pay attention to:
As you can see, "app" has been renamed by the builder/plugin to "app.14b3524f".
That's all! Thanks to those who tried to help!
PS Plugin behavior is described here

J
Javid Askerov, 2017-09-20
@HalfBloodPrince

There is no code in your JS link, but I would suggest using ref (check the documentation) and also put this code in componentDidMount , one of the lifecycle methods.

N
Ninja Mate, 2017-09-20
@victorzadorozhnyy

Are you sure you include the JS after the div?

A
Anton, 2017-09-20
@SPAHI4

In the screenshot I see the attribute async. Try to replace withdefer

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question