Flow: `import * as React from 'react'` causes deprecation warnings

Created on 21 Aug 2017  路  9Comments  路  Source: facebook/flow

With dependencies:

"flow-bin": "0.53.1",
"react-test-renderer": "15.6.1",
"react": "15.6.1",

Given a test file:

import * as React from 'react';
import renderer from 'react-test-renderer';

test('renders', () => {
  renderer.create(<div />);
});

Running the test file with Jest writes the following to the console:

  console.warn node_modules/react/lib/lowPriorityWarning.js:40
    Warning: Accessing PropTypes via the main React package is deprecated, and will be removed in  React v16.0. Use the latest available v15.* prop-types package from npm instead. For info on usage, compatibility, migration and more, see https://fb.me/prop-types-docs

  console.warn node_modules/react/lib/lowPriorityWarning.js:40
    Warning: Accessing createClass via the main React package is deprecated, and will be removed in React v16.0. Use a plain JavaScript class instead. If you're not yet ready to migrate, create-react-class v15.* is available on npm as a temporary, drop-in replacement. For more info see https://fb.me/react-create-class

Changing import * as React from 'react'; to import React from 'react'; causes these warnings to disappear.

The documentation at https://flow.org/en/docs/react/types/ recommends import * as React from 'react';

Most helpful comment

Thanks asolove.

Because we want to keep our tests free of warnings, I'd like to find a workaround.

Options:

  1. import React, { type Node } from 'react';
  2. React$Node

All 9 comments

Ah, interesting. Looks like the _interopRequireWildcard helper added by Babel has to copy properties onto a new object. So naturally it iterates over them and gets them and sets them. The React deprecation warnings are called in getters for PropTypes and createClass. So doing import * as React calls those getters just to set up the required object, even if user code doesn't use them.

I can't think of a good way around this on any level. The require wildcard is needed to know to import the namespace with React.* types. The copying is needed to preserve the semantics of imports. And there's really no way for React to know this is just ignorable library stuff rather than user code. (Maybe React could make deprecated properties non-enumerable? But that would probably have other ramifications that aren't backwards-compatible.)

Thanks asolove.

Because we want to keep our tests free of warnings, I'd like to find a workaround.

Options:

  1. import React, { type Node } from 'react';
  2. React$Node

Have the same issue after implementing flow in my project. Explicitly importing the needed types like @dgcoffman did in Option 1 got rid of the warnings.

Ran into the same issue. At least we should fix the React docs section, which directly suggests

import * as React from 'react';

I think the thing is, that really is the way we want people to do the import in order to be able to use the React types. So maybe docs should warn you about this message, but I don't think the advice itself should change.

/cc @calebmer would love to know if FB folks have a way to fix this either on the React or Flow side.

@asolove got this warnings too, I've created a pull request here to add a note on the docs about this.

I tried mucking with imports, but import * as React from 'react'; is required by Flowtype and makes sense.

A much simple solution was to just delete those two deprecated properties when running in Jest, so they're never imported: https://gist.github.com/turadg/9bcf08a7279e82a030a645250639fe6e

I hit this issue with the crypto library but only found other, worse workarounds so I'm enriching this place with the relevant error google text.

Something somewhat interesting which may clue in a different kind of fix - Node's console was able to inspect the crypto object without triggering the Getter. So I'm guessing there might be a babel workaround that doesn't trigger the getter but instead places a function in its place which would trigger the getter upon demand and replace itself. Seems a bit more complicated and would be an idea for whoever implements _interopRequireWildcard to consider. I also don't know if there's a way to get the getter.

> c = require('crypto')
{ ...
  createCredentials: [Getter],
...}
> c.createCredentials
[Function: createSecureContext]
> (node:10903) [DEP0010] DeprecationWarning: crypto.createCredentials is deprecated. Use tls.createSecureContext instead.

This probably can be closed.
/cc @vkurchatkin

Was this page helpful?
0 / 5 - 0 ratings