Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react/compat as module gives undefined __Hook #4127

Closed
1 task
GeorgeRadev opened this issue Sep 4, 2023 · 2 comments
Closed
1 task

react/compat as module gives undefined __Hook #4127

GeorgeRadev opened this issue Sep 4, 2023 · 2 comments

Comments

@GeorgeRadev
Copy link

  • Check if updating to the latest Preact version resolves the issue

Describe the bug
When trying to use vanilla JS and preact/compat
it fails with undefined currentComponent.__hooks
in function getHookState(index, type)
under Firefox and Chromium

To Reproduce
simple code with js modules:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>PReact Hello World</title>
</head>

<body>
  <div id="root"></div>

  <script type="importmap">
  {
      "imports": {
        "preact": "https://unpkg.com/[email protected]/dist/preact.mjs",
        "preact/hooks": "https://unpkg.com/[email protected]/hooks/dist/hooks.mjs",
        "react": "https://unpkg.com/[email protected]/compat/dist/compat.mjs",
        "react-dom": "https://unpkg.com/[email protected]/compat/dist/compat.mjs"
      }
  }
  </script>
  <script type="module">
    import React from 'react';
    import ReactDOM from "react-dom";

    function counter() {
      // State to store count value
      const [count, setCount] = React.useState(0);

      // Function to increment count by 1
      const incrementCount = () => {
        // Update state with incremented value
        setCount(count + 1);
      };
      return React.createElement("div", {
        className: "app"
      }, React.createElement("button", {
        onClick: incrementCount
      }, "Click Here"), count);
    }

    const rootElement = document.getElementById('root');
    const element = counter();
    preact.createRoot(rootElement).render(element);
  </script>
</body>

</html>

Steps to reproduce the behavior:

  1. create an html page with the code above and open it in the browser
  2. check the console

Expected behavior
there should not be syntax errors and the code should render a preact component

@marvinhagemeister
Copy link
Member

marvinhagemeister commented Sep 4, 2023

@GeorgeRadev Component functions cannot be called directly. They expect to be called in the context of the rendering framework. If you just call them outside that the whole rendering context needed for hooks and things will not be present, hence the error.

function App() {
  return <h1>hello world</h1>
}

// BAD: Don't do this, component is called eagerly outside of
// the rendering context.
render(App(), document.getElementById("app"));

// CORRECT
render(<App />, document.getElementById("app"));

Applying the fix to your snippet:

-    const element = counter();
-    preact.createRoot(rootElement).render(element);
+    const element = React.createElement(counter, null);
+    ReactDom.render(element, rootElement); // React v18 APIs are not supported in compat

FYI: You can also simplify your import map quite a bit by going with esm.sh:

 {
   "imports": {
    "preact": "https://esm.sh/[email protected]",
    "preact/": "https://esm.sh/[email protected]/",
    "react": "https://esm.sh/[email protected]/compat",
    "react-dom": "https://esm.sh/[email protected]/compat"
  }
}

Also you can enable helpful debug messages that warn you of issues like the one you ran into by using preact/debug:

// Import this at the top of your JS file
import "preact/debug";

@GeorgeRadev
Copy link
Author

Thank you @marvinhagemeister,
The fastest, accurate and understandable response.
Now it make sense that the function needs to be executed when the rendering is happening, the result of it has no use bore that.
Thank you once again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants