Home > database >  Why useState is throwing error when used in main App functional component?
Why useState is throwing error when used in main App functional component?

Time:06-21

Using useState works fine when used in functional child components, but for some reason doesn't work when used in the 'main' component, which is called 'App' here.

React shows 'Invalid hook call' in the console, but I checked the code 100 times and it's exactly the same as in child components, where it's working.

Is there something I should know about a difference between the 'main' component and child components? Why doesn't this work?

This is the part that renders the 'main' component (App) to the DOM (Main.jsx):

const app = App();
const appCont = crEl('div');
document.body.appendChild(appCont);
const reactRoot = createRoot(appCont);
reactRoot.render(app);

This is the simplified App-code (AppTest.jsx):

import React, { useState } from 'react';

export function App() {
    const [objectKey, setObjectKey] = useState('h09C-081');

    // todo: use objectKey

    return <div>test app</div>;
}

This is the error I'm getting: screenshot

React version used: 18.1.0 (both React and React-Dom)

CodePudding user response:

const app = App(); is not how you render your main component. It just calls the component as a function. Instead, you need to pass App to createElement (usually this is done via JSX) so that React can call it as necessary in the correct context. It's the fact that it's being called without the correct context that causes the hooks to fail; they don't know what component they're being used in (because they aren't being used in any component).

To correctly render your main component, remove the const app = App(); and either use <App /> or React.createElement(App) when calling render:

const appCont = crEl('div');
document.body.appendChild(appCont);
const reactRoot = createRoot(appCont);
reactRoot.render(<App />); // ***

or if you need not to use JSX for some reason:

const appCont = crEl('div');
document.body.appendChild(appCont);
const reactRoot = createRoot(appCont);
reactRoot.render(React.createElement(App)); // ***
  • Related