I was getting this error below in Flow type checking.
Cannot call ReactDOM.render with document.getElementById(...) bound to container because null [1] is
incompatible with Element [2].
src/index.js
26│ </Switch>
27│ </ScrollToTop>
28│ </BrowserRouter>
29│ </Provider>, document.getElementById("root"));
30│
/private/tmp/flow/flowlib_174a8121/dom.js
[1] 646│ getElementById(elementId: string): HTMLElement | null;
/private/tmp/flow/flowlib_174a8121/react-dom.js
[2] 18│ container: Element,
The code is below.
// @flow
"use strict";
import React from "react";
import ReactDOM from "react-dom";
import {createStore, applyMiddleware} from "redux";
import {Provider} from "react-redux";
import {BrowserRouter, Switch, Route} from "react-router-dom";
import Home from "./components/home";
import Detail from "./components/detail";
import LevelOfGame from "./components/level-of-game";
import NotFound from "./components/not-found";
import ScrollToTop from "./components/scroll-to-top";
import reducers from "./reducers";
const createStoreWithMiddleware = applyMiddleware()(createStore);
ReactDOM.render(<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<ScrollToTop>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/detail/:detailId" component={Detail}/>
<Route path="/level-of-game" component={LevelOfGame}/>
<Route path="*" component={NotFound} status={404}/>
</Switch>
</ScrollToTop>
</BrowserRouter>
</Provider>, document.getElementById("root"));
I believe I had to specify the type somehow in getElementById
.
So I fixed the error by storing document.getElementById("root");
in a constant variable with a type specification:
const root: any = document.getElementById("root");
The error is fixed and I hope this is useful for other folks, but I'd love to understand what was causing this error. Can anyone be so kind to tell me what this was?
The ReactDOM. render() function takes two arguments, HTML code and an HTML element. The purpose of the function is to display the specified HTML code inside the specified HTML element.
Because you won't be able to render an app to DOM without it. Your app probably has reactdom. render() in it and you don't realize it. Those are probably standalone examples—you need it once for every app.
Wrapping Up. As the article says both the render() and hydrate() function are part of the ReactDOM package for displaying content to the user. Difference between them is that with render() function all content is render at the client side, which means that both HTML and JS part would be rendered on client side.
render() currently returns a reference to the root ReactComponent instance. However, using this return value is legacy and should be avoided because future versions of React may render components asynchronously in some cases.
Aleksey L. got this first in the comments, I wanted to bring this info up to the answer level for easier visual scanning.
Flow is letting you know that the call document.getElementById("root");
can return null
in which case the app would completely crash. So let's guard against that:
const root = document.getElementById('root')
if (root !== null) {
ReactDOM.render(<App /> , root)
}
Granted, this can feel a little annoying given that in all likelihood you will be controlling the HTML you are rendering into.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With