Flow: Shouldn't ReactDom.render restrict container to HTMLElement?

Created on 28 Feb 2016  路  8Comments  路  Source: facebook/flow

In

https://github.com/facebook/flow/blob/master/lib/react.js#L236-L239

ReactDom.render takes _any_ as type of second parameter container. Same is true for similar methods.

Is there any reason why this is not _HTMLElement_?

react

Most helpful comment

Flow doesn't know for certain that an HTML element with id pad exists in the DOM, so you should add the appropriate error handling check.

var pad = document.getElementById('pad');
if (pad == null) {
  // error handling
} else {
  // render
}

You can also write an invariant-style check to simplify control flow in the case where a non-existent element is a programmer error.

var pad = document.getElementById('pad');
if (pad == null) {
  throw new Error("no pad element");
}
// `pad` is non-null here

All 8 comments

It seems to restrict it to Element now. What is the correct way check for this?

Error: src/index.js:33
 33:     document.getElementById('root')
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null. This type is incompatible with the expected param type of
 17:     container: Element,
                    ^^^^^^^ Element. See lib: /private/tmp/flow/flowlib_34dd974c/react-dom.js:17

Is this the correct way?

const root = document.getElementById('root');

if (root instanceof Element) {
  ...

Rather seems you should check for null.

Ok, I just didn't see any examples or docs. Even https://flow.org/en/docs/react doesn't mention anything about it. Maybe an oversight?

Just stumbled on this issue , while looking for the solution of my simple code

ReactDOM.render(
  <div>
    <div className="app-header">
      <Logo/> Welcome to Whinepad!
    </div>
  </div>,
  document.getElementById('pad')
);

it displayed

Error: js/source/app.js:32
32: document.getElementById('pad')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null. This type is incompatible with the expected param type of
17: container: Element,
^^^^^^^ Element. See lib: C:\Users\fake\AppData\Local\Temp\flow\flowlib_3d5529e9\react-dom.js:17

And only making dom param as any

ReactDOM.render(
  <div>
   .....
  </div>,
(document.getElementById('pad'): any) 
);

did the trick.
Can anybody tell me is it described in any docs?

Flow doesn't know for certain that an HTML element with id pad exists in the DOM, so you should add the appropriate error handling check.

var pad = document.getElementById('pad');
if (pad == null) {
  // error handling
} else {
  // render
}

You can also write an invariant-style check to simplify control flow in the case where a non-existent element is a programmer error.

var pad = document.getElementById('pad');
if (pad == null) {
  throw new Error("no pad element");
}
// `pad` is non-null here

Thanks, Sam!

Any idea why this works:

const root = document.getElementById('index');

if(root !== null) {
  ReactDOM.render(<Index />, root);
}

But not this?

const isNotNull = (value): boolean =>  value !== null;

if(isNotNull(root)) {
  ReactDOM.render(<Index />, root);
}

@matthewharwood see docs

Was this page helpful?
0 / 5 - 0 ratings