Reputation: 4460
I want to show some records in a table using React but I got this 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See for tips about how to debug and fix this problem.
import React, { Component } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
const useStyles = makeStyles(theme => ({
root: {
width: '100%',
marginTop: theme.spacing(3),
overflowX: 'auto'
},
table: {
minWidth: 650
}
}));
class allowance extends Component {
constructor() {
super();
this.state = {
allowances: []
};
}
componentWillMount() {
fetch('http://127.0.0.1:8000/allowances')
.then(data => {
return data.json();
})
.then(data => {
this.setState({
allowances: data
});
console.log('allowance state', this.state.allowances);
});
}
render() {
const classes = useStyles();
return (<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Allow ID</TableCell>
<TableCell align="right">Description</TableCell>
<TableCell align="right">Allow Amount</TableCell>
<TableCell align="right">AllowType</TableCell>
</TableRow>
</TableHead>
<TableBody> {
this.state.allowances.map(row => (<TableRow key={row.id}>
<TableCell component="th" scope="row">{row.AllowID}</TableCell>
<TableCell align="right">{row.AllowDesc}</TableCell>
<TableCell align="right">{row.AllowAmt}</TableCell>
<TableCell align="right">{row.AllowType}</TableCell>
</TableRow>
))
}
</TableBody>
</Table>
</Paper>
);
}
}
export default allowance;
Upvotes: 345
Views: 1042658
Reputation: 31
After several rounds of debugging, I discovered the true cause of the issue in my project. It was related to a method being moved into the component where it was previously defined outside. The method in question is makeStyles, commonly used like this :
const allStyles = makeStyles((theme) => ({
popupDialogContainer: {
borderRadius: 8,
padding: 24,
rowGap: 10,
backgroundColor:theme.colors.primary
},
}))();
The makeStyles method, from the React-Native-Element library, is used for configuring styles with global theme settings.
What Happened:
Upvotes: 0
Reputation: 118
if you're still getting this error by applying above all the solution, then you can do one more try by remove the node_modules Pods directory podfile.lock file yarn.lock file or package-lock.json file and delete the app and reinstall the app.
(In my case this issue arises when I switch the branch).
Upvotes: 0
Reputation: 61
My Noob Brain wrote curly braces for useState()
const {loading, setLoading} = useState(true)
Fix :
const [loading, setLoading] = useState(true)
Upvotes: 0
Reputation: 325
We have encountered an issue with folder linking through yarn
where yarn
fails to remove the links completely. This problem arose while working with the React Map Library build, and it looks like what's shown in the screenshot.
To fix this build error, follow these steps:
Run yarn unlink react
&& yarn unlink react-dom
, and your other libraries. Ideally, this command should remove all linked library folders.
You can also use the command yarn unlink --all.
Next, delete the node_modules folder in all linked repositories.
IMPORTANT!!! If rebuilding the dev server and relinking didn't solve the issue, it's possible that Yarn didn't completely clean up the links. You can manually delete them with the command rm -rf ~/.config/yarn/link/*
.
Then, relink the necessary folders (react, react-dom), and everything should work again.
Hope this helps!
Upvotes: 0
Reputation: 7044
You can only call hooks from React functions. Read more here.
Just convert the Allowance
class component to a functional component.
const Allowance = () => {
const [allowances, setAllowances] = useState([]);
useEffect(() => {
fetch('http://127.0.0.1:8000/allowances')
.then(data => {
return data.json();
})
.then(data => {
setAllowances(data);
})
.catch(err => {
console.log(123123);
});
}, []);
const classes = useStyles();
return (<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell> Allow ID </TableCell>
<TableCell align="right"> Description </TableCell>
<TableCell align="right"> Allow Amount </TableCell>
<TableCell align="right"> AllowType </TableCell>
</TableRow>
</TableHead>
<TableBody>{
allowances.map(row => (<TableRow key={row.id}>
<TableCell component="th" scope="row">{row.AllowID}</TableCell>
<TableCell align="right"> {row.AllowDesc}</TableCell>
<TableCell align="right"> {row.AllowAmt}</TableCell>
<TableCell align="right">{row.AllowType}</TableCell>
</TableRow>
))
}
</TableBody>
</Table>
</Paper>
);
};
export default Allowance;
Upvotes: 116
Reputation: 1051
In my Next.js app, I encountered the same issue. In my case, I believe it was a cache-related problem. Running the project after removing the ".next" folder resolved the issue. I hope that removing the build folder in React will have the same effect.
Upvotes: 4
Reputation: 3253
In my case , the issues was because somehow , I was generating two react trees because I had two ReactDOM.render
calls . One in index.js and other one in a component. Error goes away , after I removed one of the ReactDOM.render
call like this
export const RenderTopMenuResultPage = (props) => {
ReactDOM.render(
<CreateTopMenuResultPage />,
document.getElementById('result-page-sort-menu')
)
}
to
export const RenderTopMenuResultPage = (props) => {
return <CreateTopMenuResultPage />;
};
Upvotes: 0
Reputation: 5795
In my case, I called the functional component as a function myComponent()
instead of using it as a component, i.e. <myComponent />
, and that solved my issue.
Upvotes: 0
Reputation: 1759
I was using microfrontend architecture. The problem was that the react
dependencies were not shared during the compilation in Webpack.
Example nx config:
module.exports = {
name: 'mfe',
remotes: ['mfe-remote'],
additionalShared: ['react', 'react-dom', /* 'any-react-library' used by both module */],
}
Upvotes: 0
Reputation: 61
For those who have a Monorepo setup (whether it's multiple React projects or a combination of React and React Native):
I encountered an error after updating my React Native project to RN 70 and React 18 while executing the app via the Metro bundler:
1- Ensure a unified version of react, react-dom, and react-redux is used across all packages.
2- (ignore if you don't have a react native package) Verify that both react and react-redux aren't hoisted for the mobile (React Native package). This means both packages should be present in the node_modules directory of the mobile package. Learn more about nohoist here.
A useful tip:
yarn why react
This command displays which packages have react as a dependency. Additionally:
yarn list react
This command presents the versions of react in your project. Ideally, there should only be one version.
The same applies for react-redux and react-thunk.
Upvotes: 0
Reputation: 1600
Be aware of import issues- For me the error was about failing imports / auto imports on components and child components. Had nothing to do with Functional classes vs Class components.
{ MyComponent }
is used and export default
used in the component the import should say import MyComponent
{TextComponent, ButtonComponent, ListComponent} from '../../common'
Try to comment out some components in the file that gives the error and you can test if this is the problem.
Upvotes: 2
Reputation: 1146
This might also occur because your hook is called below any asynchronous or nested functions. You need to move the hook to the top level of the function body.
In your case, it looks like you're using a hook for class component. Consider changing the class component to a function component and then using the hook inside the top-level of the function component.
Upvotes: 0
Reputation: 24950
There are many reasons for this to happen. One of which is , when the installation of the packages are done out of scope. It tends to get confused between two react apps.
Explanation:
The packages shouldn't be installed in different levels.
The mistake
app
|node_modules <-- some packages installed here
|package.json
node_modules
package.json <-- some packages installed here
Correct Way
app
|node_modules
|package.json <-- install all the packages at the same heirarchy
Upvotes: 2
Reputation: 783
This occured for me when improperly destructuring the response from an axios.get
server call. I changed:
const { retrievedUser } = await axios.get('www.mysite.com/user/userid')
to:
const { data: retrievedUser } = await axios.get('www.mysite.com/user/userid')
Upvotes: 0
Reputation: 20088
In mycase i have used useCallback hook inside class component due to this i had a error mentioned in the question
Error:
import React, { useCallback } from 'react'
import { FormControlLabel, Switch, withStyles } from '@material-ui/core'
const styles = {
root: {
alignItems: 'center',
display: 'flex',
height: '50px',
justifyContent: 'center',
padding: 0,
width: '90px',
},
switchBase: {
'& + $track': {
backgroundColor: 'lightblue',
},
'&$checked': {
color: 'lightblue',
transform: 'translateX(40px)',
},
},
thumb: {
borderRadius: '0px',
height: '15px',
marginTop: '8px',
transform: 'translateX(19px)',
width: '15px',
},
track: {
borderRadius: '0px',
height: '20px',
width: '40px',
},
}
class SwitchLabels extends React.Component {
state = {
checked: false,
}
handleChange = React.usecallback(event => { // here i have used useCallback hook
this.props.changeStatus(event.target.checked)
this.setState({ checked: event.target.checked })
}, [])
render() {
return (
<FormControlLabel
control={
<Switch
classes={this.props.classes}
checked={this.state.checked}
onChange={this.handleChange}
disableElevation
disableRipple
style={{ backgroundColor: 'transparent' }}
value={this.state.checked}
color='primary'
/>
}
labelPlacement='start'
label={'Show inactive'}
/>
)
}
}
export default withStyles(styles)(SwitchLabels)
Solution:
import React from 'react'
import { FormControlLabel, Switch, withStyles } from '@material-ui/core'
const styles = {
root: {
alignItems: 'center',
display: 'flex',
height: '50px',
justifyContent: 'center',
padding: 0,
width: '90px',
},
switchBase: {
'& + $track': {
backgroundColor: 'lightblue',
},
'&$checked': {
color: 'lightblue',
transform: 'translateX(40px)',
},
},
thumb: {
borderRadius: '0px',
height: '15px',
marginTop: '8px',
transform: 'translateX(19px)',
width: '15px',
},
track: {
borderRadius: '0px',
height: '20px',
width: '40px',
},
}
class SwitchLabels extends React.Component {
state = {
checked: false,
}
handleChange = event => { // after removing useCallback working fine
this.props.changeStatus(event.target.checked)
this.setState({ checked: event.target.checked })
}
render() {
return (
<FormControlLabel
control={
<Switch
classes={this.props.classes}
checked={this.state.checked}
onChange={this.handleChange}
disableElevation
disableRipple
style={{ backgroundColor: 'transparent' }}
value={this.state.checked}
color='primary'
/>
}
labelPlacement='start'
label={'Show inactive'}
/>
)
}
}
export default withStyles(styles)(SwitchLabels)
Upvotes: 0
Reputation: 7671
In my case, it's come from the Chrome Extension: Loom. But it can come from any extension written via React. Crazy world, isn't it? Just disable the extension resolves the error.
Upvotes: 0
Reputation: 653
Happens to me when I used to call useNavigate() on a certain function upon onClick.
Upvotes: 4
Reputation: 64
with NPM npm install react@latest react-dom@latest with YARN yarn add react@latest react-dom@latest
Upvotes: 2
Reputation: 1066
I had the same issue, and it got resolved after editing launch.json file for vscode and changing the configurations type by removing 'pwa-' from the type:
So, instead of:
"type": "pwa-node",
It should be:
"type": "node",
Upvotes: 0
Reputation: 1442
For me this issue was caused by the webpack setting resolve.symlinks
(https://webpack.js.org/configuration/resolve/#resolvesymlinks), which was set to false
:
resolve: {
symlinks: false,
Because of this the symlink to React from another package couldn't be resolved and caused the Invalid Hook Call
error.
Setting it to true
or simply omitting it (apparently it defaults to true
) solved the problem:
resolve: {
symlinks: true,
Upvotes: 0
Reputation: 832
In my case, I was using navigation in App.js where I have Stack Navigator & assigning all my screens. Please remove below line if you have that.
const navigation = useNavigation()
Upvotes: 2
Reputation: 2001
I'm using Electron. I tested all the answers above, even stripping down to the base app, and found it was still happening.
Turns out if you are using electron (specifically expo-electron, in my case), it has it's own webpack configuration, and you need to white-list redux in the webpack config. My electron-webpack.js file looks like this:
const { withExpoAdapter } = require("@expo/electron-adapter");
// Provide any overrides for electron-webpack: https://github.com/electron-userland/electron-webpack/blob/master/docs/en/configuration.md
module.exports = withExpoAdapter({
projectRoot: __dirname,
whiteListedModules: ["react-redux"],
});
Upvotes: 0
Reputation: 122
Bad:
import { useDispatch } from 'react';
Good:
import { useDispatch } from 'react-redux';
I remember It happened to me once that I imported useDispatch from ‘react’ as opposed to import it from ‘react-redux’ It was very difficult to figure out, because code seamed right from every angle, I just could not guess it for hours lol
Upvotes: 0
Reputation: 20088
I had same problem while I use useLocation
hook in class component
Error:
import React from "react";
import { useLocation } from "react-router-dom";
class ShowTheLocation extends React.Component {
const location = useLocation();
render() {
return <div>You are now at {location.pathname}</div>;
}
}
Solution: I have converted class component to function component then issue resolved
import React from "react";
import { useLocation } from "react-router-dom";
const ShowTheLocation = () => {
const location = useLocation();
return <div>You are now at {location.pathname}</div>;
}
Upvotes: 0
Reputation: 375
Another reason this error could happen is if you have declared your functional components with an arrow function signature instead of a function signature.
Ex: Change your functional component declaration from an arrow function
export const Counter = (props) => {}
TO function declaration
export function Counter (props) {}
And that will help resolve the issue. At least in my case, it did.
Upvotes: 1
Reputation: 614
I got this error when I linked a local library. The following solved my problem.
Upvotes: 1
Reputation: 3730
My error was with the export at the end, I had the following:
I should have removed the brackets:
Upvotes: 1
Reputation: 1459
If your front-end work is in its own folder you might need to install @material-ui/core @material-ui/icons inside that folder, not in the backend folder.
npm i @material-ui/core @material-ui/icons
Upvotes: 2
Reputation: 325
To anybody who might looking for a FAST solution to this issue :
You might be breaking the Rules of Hooks. To Solve this Problem move the :
👉const [x, setX] = useState(0);
to the TOP-LEVEL of the function that calling it And not outside of the function.
function App() {
👉const [t, setTime] = useState("");
return (
<div>
<h1>{t}</h1>
<button onClick={() => setTime(t+1)}>Get Time</button>
</div>
);
}
👍 https://reactjs.org/warnings/invalid-hook-call-warning.html
Upvotes: 1
Reputation: 834
I ran into this same issue while working on a custom node_module
and using npm link
for testing within a cra
(create react app).
I discovered that in my custom node package
, I had to add a peerDependencies
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0"
},
After added that into my package.json
, I then re-built
my custom package.
Then in the CRA
, I blew away node_modules
, re npm install
, Re-do the npm link <package>
, and then start the project.
Fixed everything!
Upvotes: 2