Cannot set property createElement of #<Object> which is only a getter
Asked Answered
H

1

8

Description

What you are reporting: I am following this set of instructions on how to setup React hot loarder. But when I go to step 3 where I put the patch, it breaks in to the one below.

Expected behavior

What you think should happen: Should work properly

Actual behavior

image

Environment

React Hot Loader version: next

Run these commands in the project folder and fill in their results:

  1. node -v: 7.9.0
  2. npm -v: 4.2.0

Then, specify:

  1. Operating system: Windows 10
  2. Browser and version: Latest Chrome

Reproducible Demo

https://github.com/abarcenas29/preact-sandbox-v0/blob/wip/hot-reloader/src/main.js

branch: wip-hot-reloader

Instructions:

  • yarn
  • yarn run postinstall
  • yarn run start:dev
Helfant answered 28/5, 2017 at 16:13 Comment(0)
S
11

I don't have enough reputation to post comments, so I have to write an answer which is not exactly a solution to the problem, but still...

The error you are receiving is due to react-hot-loader/patch requiring the actual react module and patching its createElement function with a new one. See it here: react-hot-loader/lib/patch.dev.js:179

The main problem is that in the webpack config react module is resolved to preact-compat which apparently does not allow setting new values and so Hot Reload fails to run all together.

Hope this answers your question. Being as it is - I think hot reload will not work in that setup.

EDIT: Found an easy solution. Change the webpack.config.js resolve block to this, to point react to your own script:

// resolve for preact
webpack.resolve = {
  alias: {
    react: path.resolve(__dirname, 'react.js')
    // the rest goes as before
  }
}

Now create the react.js file and put this inside (change paths and names as you see fit):

var preact = require('preact-compat');

var react = {};
// Copy object properties to a new object which will allow react-hot-loader to do its magic
Object.keys(preact).forEach(function(key) {
    react[key] = preact[key];
});

module.exports = react;

And done! HMR is now working.

Socinus answered 1/6, 2017 at 9:55 Comment(6)
Thanks. I'm having suspicions of that. I'll test this theory out later and see if it is. I'll come back and award you if this was the case. Again, Thanks!!!Helfant
This is the place where the import of react takes place: react-hot-loader/lib/patch.dev.js:7 and if you try setting the createElement property here yourself - the exact same error occurs. Good luck!Socinus
@MrA the problem was so interesting, I couldn't let it go :D Edited the answer with the code which solves your problem. HMR is now working. Cheers!Socinus
I converted my repo from preact to react and it manage to work as you had said. I tried doing your suggestion and the behavior is that every time I change something, it refreshes the page. Hence, the HMR stopped working.Helfant
It reloads the page only if you edit the main.js since it is a top level file containing the app component. If you edit App.js or any child components imported from App.js HMR will work properly. However, If you are not strictly tied to preact than using the actual react is a better way to go IMHO.Socinus
Alongside react and react-dom, you could also alias 'preact-compat': 'preact-compat/dist/preact-compat'. That would work as well.Equivalent

© 2022 - 2024 — McMap. All rights reserved.