preact: 10.0.0-alpha.1 - __hooks of undefined with render-to-string

There’s an odd bug when using hooks together with render-to-string.

What I had was a simple component with the useState hook. Rendered on the client this was fine, on the server it resulted in: Uncaught TypeError: Cannot read property '__H' of undefined.

At first I thought this had something to do with render-to-string because the error also occurred when I replaced preact’s render function on the client with render-to-string. After some more investigation this wasn’t actually a bug in that library but rather in preact/hooks, let me explain:

The __H in the error stands for __hooks that can’t be read because currentComponent is undefined. This is defined when you use preact’s render function. In this codesandbox you can see that at first render-to-string throws the error, after that the same component renders fine (normal render function), then render-to-string works!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

Leaving this for the next person who makes the mistake I made:

If you are new to Preact and you found this bug by searching “Cannot read property ‘__H’ of undefined” on Google: That error message can also happen if you call useState and you are not actually in a component function. I recommend enabling “preact/debug”: https://preactjs.com/guide/v10/debugging/

Thanks for pointing folks in the right direction @mcclure! I wonder if it would be worth creating a page on preactjs.com that lists out common error messages with fixes for each? That way anyone googling gets a nice resource with a clear answer.

I’ve landed here because of

Uncaught (in promise) TypeError: Cannot read property '__hooks' of undefined
// fired from 
var hooks = currentComponent.__hooks 

the cause was vs-code auto-import looking like this

import { useState, useCallback } from 'preact/hooks/src';
// instead of this
import { useState, useCallback } from 'preact/hooks'; 

Had a look into this and the issue is that we never set vnode._component anywhere in render-to-string. This will lead to currentComponent always being null in preact/hooks and finally to an exception when we try to access currentComponent.__hooks a few lines later.

@didymu5 yes by using the new version of render-to-string

Was this ever resolved? I still get the undefined error, with a built package. In development the hooks work fine. However, after I build and serve the built .js package, I get the following error.

hooks.module.js:1 Uncaught TypeError: Cannot read property '__H' of undefined
    at r (hooks.module.js:1)
    at i (hooks.module.js:1)
    at o (hooks.module.js:1)
    at S.p [as constructor] (index.js:6)
    at S.x [as render] (preact.min.js:1)
    at j (preact.min.js:1)
    at C (preact.min.js:1)
    at N (preact.min.js:1)
    at _ (preact.min.js:1)
    at v (preact.min.js:1)
"devDependencies": {
    "eslint": "^4.5.0",
    "identity-obj-proxy": "^3.0.0",
    "if-env": "^1.0.0",
    "jest": "^21.2.1",
    "microbundle": "^0.6.0",
    "node-sass": "^4.5.3",
    "preact-cli": "^2.0.2",
    "preact-render-to-string": "^3.7.0",
    "preact-widget-scripts": "^0.6.0",
    "sass-loader": "^6.0.6"
  },
  "dependencies": {
    "preact": "^10.0.0-rc.1",
    "preact-compat": "^3.17.0",
    "preact-habitat": "^3.1.0",
    "preact-render-to-string": "^4.1.0",
    "preact-router": "^2.5.7"
  },