Pedro Relvas
Pedro Relvas

Reputation: 679

React - Invalid hook call & class Component

I know that hooks are the oposite of a class component - don't get me wrong, I just don't know how a simple line of code can make this error appear and what I have to change in that line to make it work in an class component. I got the following example which works very well with .jsx type of file and with functional components.

Codesandbox example one

This code is just a simple way of share a state between components. So we got the file extendDiv where we have our state and a simple function to change that state; then we have a global file, to got that state and distribute it to all of our components: son (filho) and father (pai). In the codesandbox example one it works just fine, but when I do the exactly same thing but with a class component in the App.jsx and with some typescript files, it gives me the following error in the following code:

global.isDivExtended = extendDiv();
//Invalid hook call. Hooks can only be called inside of the body of a function component.

You can see all the code and try it here: Codesandbox example two

What I should do here to make it work in an class component? I've already tried to bind the global and to use the this... Thank you very much.

Upvotes: 1

Views: 338

Answers (1)

pitamer
pitamer

Reputation: 1064

React hooks can't be called from class components.

You can either convert said class component to a function component, or leave it as a class component and manage state the good ol' class-component way. Converting to a function should be preferred.

It seems the sandbox doesn't have all the files, so I can't know for sure, but i believe this might work:

import * as React from "react";
import "./styles.css";
import Father from "../src/components/father";
import global from "./global";
import extendDiv from "./extendDiv";

function App(props) {
  let [dateVar, setDateVar] = React.useState({ date: new Date() })
  global.isDivExtended = extendDiv();

  return (
      <>
        <Father></Father>
      </>
  )
}

export default App;

Alternatively, you can write a higher-order component wrapper for your hook, so that you can pass the logic of a hook as a prop to your class component, as explained here. However, if possible, I would suggest avoiding it; it's messy and it's harder to test. Function components are way more fun to write (and read), plus it seems they are the future of React.

Upvotes: 3

Related Questions