react: React app not rendering in IE11 and below

Do you want to request a feature or report a bug? BUG

What is the current behavior? App doesn’t render in IE11 and below.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/reactjs/69z2wepo/).

  • Build React app with Webpack
  • Launch IE11 or below (not an emulator)
  • You will see a blank screen or half-compiled React app with the following error: 24f8f6e8-afde-11e6-9a6f-a3cc6355f55c

What is the expected behavior?

  • To render as it does in Chrome, Firefox, etc.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? We’ve temporarily shrink-wrapped our dependencies so that we can continue to serve our app. We’re starting to believe that it’s coming from a dependency that react, apollo or webpack may be relying on…

Shrink-wrapped versions of our dependencies (left is the new one that’s broken and the right one is the old one that continues to work across all browsers) https://www.diffchecker.com/SyaJUcsk

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 22
  • Comments: 49 (6 by maintainers)

Commits related to this issue

Most upvoted comments

This bit me too after upgrading to React 15.4 and I had to spend some time figuring it out. So I’m posting this to help others in the same situation.

If you are using react-hot-loader v3 for hot-reloading in DEV environment you need to load react-hot-loader/patch after babel-polyfill does. So Webpack’s entry field should look like the following to work correctly with react 15.4.x, react-hot-loader v3 and webpack-dev-server:

entry: [
   'babel-polyfill', // Load this first
   'react-hot-loader/patch', // This package already requires/loads react (but not react-dom). It must be loaded after babel-polyfill to ensure both react and react-dom use the same Symbol.
   'react', // Include this to enforce order
   'react-dom', // Include this to enforce order
   './index.js' // Path to your app's entry file
]

Hope this helps 😉

Thank you to everyone on this thread, esp. @gaearon and @damonbauer. In case this helps someone else, here are the changes I ended up making:

image

I fixed this by enforcing a load order in my webpack bundle:

  1. babel-polyfill
  2. react
  3. react-dom

Thanks for your patience and your infinite wisdom 😉 @gaearon

Nothing worked for me either, changing the order of the polyfill or anything else. What worked for me is adding this JS link in the index.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser-polyfill.min.js"></script>

After adding this I was successfully able to run the react app in IE 11

The problem is that React doesn’t “recognize” its own element. This likely happens because of the failed $$typeof check. Somehow react and react-dom no longer “agree” on the $$typeof value which should be typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103.

This might mean that react and react-dom somehow get different results when testing for Symbol polyfill. For example if you load a polyfill after react initializes but before react-dom does, you might get this issue.

To debug it further I recommend finding this fragment in your bundle:

var r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103;

You should see it two times (once from react and once from react-dom):

screen shot 2016-11-30 at 19 01 14 screen shot 2016-11-30 at 19 01 00

Try adding logs of r value and see if they’re different. If they are, you’d need to figure out why react and react-dom get different values when checking for existence of Symbol.

The reason this is new in 15.4.0 is because there only used to be one version of this code, but now it’s in both packages (intentionally).

I was able to get this working by just including the 'core-js/modules/es6.symbol' BEFORE 'react'.

'core-js/modules/es6.symbol' is much smaller than 'babel-polyfill' so others may want to consider trying this as well

bitmoji

@qborreda The solution is to load babel-polyfill before react and react-dom.

For Webpack users this means making the main entry an array and the first element of the array is gonna be babel-polyfill, as shown here: https://github.com/catamphetamine/webpack-react-redux-isomorphic-render-example/blob/4d6208662157cfc6bac115fe5dff956c4976145c/client/webpack/webpack.config.js#L23

In case somebody else comes across this, I was using the commons chunk plugin which was loading react in before the poly. To get around this I ended up with:

entry: {
    'commons': ['babel-polyfill', 'react', 'react-dom'],
    'app': './src/js/app/main.tsx'
}

Not sure if that is the ‘right’ way but it is the only way with commons I found that worked.

I tried all of the above and none of it worked except for a tweak on @jkilesc 's work. So the order of imports matter.

You would think your entry script having the polyfills at the top would be different than including it as a separate file in your entry array like babel-polyfill? No.

So from

// index.js
require('core-js/modules/es6.symbol')
require('core-js/modules/es6.promise')
import React from 'React'

to

// webpack.config.js
...
  entry: {
    polyfill: [
      path.resolve(__dirname, '../src/polyfill.js'),
    ],
    main:
...

plugins:[
...
    new webpack.optimize.CommonsChunkPlugin({
      // The order of this array matters
      names: ["main", "vendor", "polyfill"],
      minChunks: 2
    }),
...
]
...

// index.js
- require('core-js/modules/es6.symbol')
- require('core-js/modules/es6.promise')

// polyfill.js
// Absolutely ensure these are loaded first
require('core-js/modules/es6.symbol')
require('core-js/modules/es6.promise')

Why? During the transpile the order of libraries seems to shift so that the polyfill is loaded after React? But there you go. This also worked where babel-polyfill on my entry script did not.

This just started happening to me again in the last week in IE11 (ive resolved this same bug in the past using the above suggestions).

  "dependencies": {
    "babel-core": "^6.17.0",
    "babel-loader": "^6.2.5",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-runtime": "^6.15.0",
    "babel-polyfill": "^6.16.0",
    "babel-preset-es2015": "^6.14.0",
    "babel-preset-react": "^6.11.1",
    "babel-preset-stage-0": "^6.3.13",
    "babel-runtime": "^6.11.6",
    "better-npm-run": "0.0.11",
    "classnames": "^2.2.5",
    "css-loader": "^0.25.0",
    "currency-formatter": "^1.0.2",
    "debug": "^2.2.0",
    "exports-loader": "^0.6.3",
    "extract-text-webpack-plugin": "^1.0.0",
    "file-loader": "^0.9.0",
    "formsy-react": "^0.18.1",
    "fs-extra": "^0.30.0",
    "html-webpack-plugin": "^2.22.0",
    "imports-loader": "^0.6.5",
    "ip": "^1.1.2",
    "json-loader": "^0.5.4",
    "lodash": "^4.11.2",
    "moment": "^2.10.6",
    "node-sass": "^3.4.2",
    "normalize.css": "^4.1.1",
    "numeral": "^1.5.3",
    "pure-render-decorator": "^1.1.0",
    "react": "^15.0.0",
    "react-ab-test": "^2.0.1",
    "react-bootstrap": "^0.30.3",
    "react-cookie": "^1.0.5",
    "react-datetime": "^2.6.0",
    "react-document-meta": "^2.0.3",
    "react-dom": "^15.0.0",
    "react-redux": "^4.4.5",
    "react-router": "^2.8.0",
    "react-router-scroll": "^0.2.0",
    "react-select": "1.0.0-rc.1",
    "react-slick": "^0.14.3",
    "react-sticky": "^5.0.5",
    "react-telephone-input": "^3.5.0",
    "redux": "^3.6.0",
    "redux-thunk": "^2.0.0",
    "rimraf": "^2.5.4",
    "sass-loader": "^4.0.0",
    "seamless-immutable": "^6.1.0",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.6",
    "validator": "^5.2.0",
    "webpack": "^1.12.14",
    "whatwg-fetch": "^1.0.0",
    "yargs": "^5.0.0"
  },

The error:

SCRIPT5022: Objects are not valid as a React child (found: object with keys {$$typeof, type, key, ref, props, _owner, _store}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of 'RedBoxError'.
File: vendor.ab56ae7d3f092ad6e17f.js, Line: 1391, Column: 6

I did, @gaearon. It didn’t make sense why it would work in Chrome and Firefox but not in IE11 and below. Thoughts?

For those who has the error, but nothing above worked: I’ve had same exact error, but the cause was completely different. There was code where react components were shared between iframes, but components to have different $$typeof value in different iframes, which caused the error. Although this worked with other browsers, IE11 had the error.

@FarhadG I hit this on my current project and had to include the Symbol polyfill. I do this by adding a polyfills.js to my entry point that looks like:

/**
 * Place any polyfills here. This project uses core-js:
 * https://github.com/zloirock/core-js
 *
 * ES6:
 * https://github.com/zloirock/core-js/tree/master/es6
 */

//...

// We need Symbol support for some React optimizations
require('core-js/modules/es6.symbol')

Edit: We use the babel-preset-react-optimize package

Maybe you enabled babel-plugin-react-inline-elements. It requires a Symbol polyfill and won’t work without it. See https://github.com/facebook/react/issues/5138.

This is a react-hot-loader issue because I only have it in dev mode and I’m not having it in production mode. Adding babel-polyfill before react-hot-loader/patch fixes this bug.

Hi,

@gaearon, here’s my investigation in order to answer https://github.com/facebook/react/issues/8379#issuecomment-263962787

Facing the same issue I tried to see why React.isValidElement was not recognizing some react elements. Looking through react and react-dom code, I thought that there was no reason why react and react-dom would not agree on what REACT_ELEMENT_TYPE was, unless you require the polyfill between requiring react and react-dom for the first time. But importing them together should not cause a problem.

Indeed, https://github.com/facebook/react/blob/v15.4.2/src/shared/utils/ReactElementSymbol.js#L17 is declared at module loading time and used everywhere in the library. So generating elements with ReactDOM.render should not have been an issue, it had to come from somewhere else.

I ended up finding that the elements causing an issue were created by babel-runtime, because the logic from ReactElementSymbol was duplicated there, but with the presence of the polyfill: https://github.com/babel/babel/blob/v6.22.0/packages/babel-helpers/src/helpers.js#L20

There is an issue closed as ‘won’t fix’ on babel-runtime: https://github.com/babel/babel/issues/2517 because react won’t share the REACT_ELEMENT_TYPE variable.

In my case, I am guessing that the issue is not due to our upgrade to 15.4 but a change of structure in our application. We can now understand why we need to import the polyfill beforehand, and it’s because of babel-runtime and not react.

Hope this will help others being in the same scenario.

I ran into this when adding babel-polyfill to our react-redux app that was made using the asp.net core 2 template. This template splits up your webpack config into two separate configuration files (webpack.config.js and webpack.config.vendor.js). You need to modify the vendor array in webpack.config.vendor.js and put babel-polyfill at the top in order to get this to work.

I also had to fully clean up my environment (namely delete the wwwroot/dist folder) and rebuild the project in order for the changes to get properly picked up.

This is expected to not work:

require('core-js/modules/es6.symbol')
require('core-js/modules/es6.promise')
import React from 'React'

ES imports are hoisted by spec (which Babel follows). Even if you put require() before it, it will be executed later.

Use this lint rule to protect against this in the future.

I’m going to close this because it doesn’t appear to be a bug. It’s unfortunate this broke some apps but it’s very hard to protect against cases like this. In general my recommendation is that you should run any global polyfills before any other code in the bundle. Since polyfills are effectively modifying the environment, one should take care to do that consistently.