Using React Hooks on a legacy web page gives "Invalid hook call" error message

Viewed 142

I'm trying to make a react component that runs on an existing HTML page of a legacy web application (aspx webforms in visual studio):

<div id="my-div" data-first-prop="1" data-second-prop="2"></div>

But I want to use the functions and "Hooks" approach, not the older Component classes.

components/Page.tsx:

import React, { useState } from 'react';

function Page(props) {
  // const [count, setCount] = useState(0);
  return (
    <div>
      <h1>
        props: {props.firstProp} and {props.secondProp}!
      </h1>
    </div>
  );
}

export default Page;

index.tsx:

import React from 'react';
import { createRoot } from 'react-dom/client';
import Page from './components/page';

const container = document.getElementById('my-div');
const root = createRoot(container);

root.render(
  <Page
    firstProp={container.getAttribute('data-first-prop')}
    secondProp={container.getAttribute('data-second-prop')}
  />
);

This code runs fine, but when I uncommented line 10 to get state:

const [count, setCount] = useState(0);

...I get the infamous "Invalid hook call" error message:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

I've been all through that linked help page with no success. Running

npm link node_modules/react

Just gives me git-related error messages. (?)

It might be multiple versions of react, when I run

npm ls react

I get:

+-- react-dom@18.1.0
| `-- react@18.1.0 deduped
`-- react@18.1.0

But I've got no clue what that means, where any of those are, or how to fix that.

Can anyone give me a hint on what to do about duplicates, or see what else I'm doing wrong?

2 Answers

The way you invoke rendering your component while appearing neat and syntactically correct, somehow confuses React:

root.render(CustomQuestionPage(props));

You need to change it to:

root.render(<CustomQuestionPage
             firstProp={container.getAttribute('data-first-prop')} 
             secondProp={container.getAttribute('data-second-prop')}
            />);

You can use this sample sandbox for reference.

You never use the empty state, I'd either initialize it like this

const [count, setCount] = useState(props);

or this

const [count, setCount] = useState(props.firstProp);

Or at least increasing the zero value and using the result.
Actually it's a wild guess that this will change something.
Here is the example with zero value: https://reactjs.org/docs/hooks-state.html

Related