我想使用 React 在表中显示一些记录,但出现此错误:
无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一: 您可能有不匹配的 React 版本和渲染器(例如 React DOM) 您可能违反了 Hooks 规则 您可能在同一个应用程序中拥有多个 React 副本 请参阅提示关于如何调试和解决这个问题。
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;
当我使用 npm link
安装我使用 cra
构建的本地库时,我遇到了这个问题。我找到了答案 here。字面意思是:
当您使用 npm link 或等效项时,也会出现此问题。在这种情况下,你的打包器可能会“看到”两个 React——一个在应用程序文件夹中,一个在你的库文件夹中。假设“myapp”和“mylib”是同级文件夹,一种可能的解决方法是从“mylib”运行“npm link ../myapp/node_modules/react”。这应该使库使用应用程序的 React 副本。
因此,运行命令:npm link <path_to_local_library>/node_modules/react
,例如。在我的情况下,项目目录中的 npm link ../../libraries/core/decipher/node_modules/react
已经解决了这个问题。
你只能从 React 函数中调用钩子。阅读更多here。
只需将 Allowance
类组件转换为功能组件即可。
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;
setAllowances
像 this.setState({allowances: data})
一样工作
setAllowances
像 this.setState 一样是异步的。因此您在 setAllowances
之后记录 allowances
,它将记录 old allowances
。
您可以通过调用一个箭头函数来使用“导出默认值”,该函数通过 MaterialUI 类对象道具传递它返回其 React.Component,而后者又将在组件渲染()中使用。
class AllowanceClass extends Component{
...
render() {
const classes = this.props.classes;
...
}
}
export default () => {
const classes = useStyles();
return (
<AllowanceClass classes={classes} />
)
}
对我来说,错误是在导出的函数默认值之外调用函数 useState
昨天,我缩短了代码(只是添加了<Provider store={store}>
),仍然遇到了这个无效的钩子调用问题。这让我突然意识到自己犯了什么错误:我没有在那个文件夹中安装 react-redux 软件。
我已经在另一个项目文件夹中安装了这个软件,所以我没有意识到这个软件也需要它。安装后,错误消失了。
当你错误地从 react-redux 声明 useDispatch 时,也会出现此错误:当你走时:
const dispatch = useDispatch
而不是:
const dispatch = useDispatch();
(即记得添加括号)
redux
react-redux
软件包有关(但存在于 monorepo 的顶层)。
complementing the following comment
对于那些使用 redux 的人:
class AllowanceClass extends Component{
...
render() {
const classes = this.props.classes;
...
}
}
const COMAllowanceClass = (props) =>
{
const classes = useStyles();
return (<AllowanceClass classes={classes} {...props} />);
};
const mapStateToProps = ({ InfoReducer }) => ({
token: InfoReducer.token,
user: InfoReducer.user,
error: InfoReducer.error
});
export default connect(mapStateToProps, { actions })(COMAllowanceClass);
我的共享库之间的不同版本的反应似乎是问题(16和17),都改为16。
将此添加到您的 package.json
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
来源:https://robkendal.co.uk/blog/2019-12-22-solving-react-hooks-invalid-hook-call-warning
您可以将类组件转换为钩子,但 Material v4 有一个 withStyles HOC。 https://material-ui.com/styles/basics/#higher-order-component-api 使用此 HOC,您可以保持代码不变。
我刚刚开始使用钩子,当我在函数中调用 useEffect 时收到上述警告:
然后我必须将 useEffect 移到函数之外,如下所示:
const onChangeRetypePassword = async value => {
await setRePassword(value);
//previously useEffect was here
};
//useEffect outside of func
useEffect(() => {
if (password !== rePassword) {
setPasswdMismatch(true);
}
else{
setPasswdMismatch(false);
}
}, [rePassword]);
希望对某人有所帮助!
就我而言,我在 FlatList
的 renderItem
属性中传递了组件名称,而不是函数。它在早期工作,因为我的组件是一个功能组件,但是当我在其中添加挂钩时,它失败了。
前:
<FlatList
data={memberList}
renderItem={<MemberItem/>}
keyExtractor={member => member.name.split(' ').join('')}
ListEmptyComponent={
<Text style={{textAlign: 'center', padding: 30}}>
No Data: Click above button to fetch data
</Text>
}
/>
后:
<FlatList
data={memberList}
renderItem={({item, index}) => <MemberItem item={item} key={index} />}
keyExtractor={member => member.name.split(' ').join('')}
ListEmptyComponent={
<Text style={{textAlign: 'center', padding: 30}}>
No Data: Click above button to fetch data
</Text>
}
/>
就我而言,只是我的 App.js 上的这一行代码导致了这种情况,让我在调试中损失了 10 个小时。 React Native 和 Expo 无法指出这一点。我做了 StackOverflow 和 github 上的所有事情,甚至是应该解决这个问题的反应页面,但问题仍然存在。我不得不开始一点一点地拆开我的代码才能找到罪魁祸首
**const window = useWindowDimensions();**
它是这样放置的:
import * as React from 'react';
import { Text, View, StyleSheet, ImageBackground, StatusBar, Image, Alert, SafeAreaView, Button, TouchableOpacity, useWindowDimensions } from 'react-native';
import Constants from 'expo-constants';
import Whooksplashscreen11 from './Page1';
import Screen1 from './LoginPage';
import Loginscreen from './Login';
import RegisterScreen1 from './register1';
import RegisterScreen2 from './register2-verifnum';
import RegisterScreen3 from './register3';
import RegisterScreen4 from './register4';
import RegisterScreen5 from './register5';
import RegisterScreen6 from './register6';
import BouncyCheckbox from "react-native-bouncy-checkbox";
import LocationPermission from './LocationPermission.js'
import Selfieverif1 from './selfieverif1'
import Selfieverif2 from './selfieverif2'
import AddPhotos from './addphotos'
// You can import from local files
import { useFonts } from 'expo-font';
// or any pure javascript modules available in npm
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
//FontAwesome
import { library } from '@fortawesome/fontawesome-svg-core'
import { fab, } from '@fortawesome/free-brands-svg-icons'
import { faCheckSquare, faCoffee, faFilter, faSearch, } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'
import Icon from "react-native-vector-icons/FontAwesome5";
import MyTabs from './swipepage'
library.add(fab, faCheckSquare, faCoffee, faFilter, faSearch,);
const window = useWindowDimensions();
const Stack = createNativeStackNavigator();
function App() {
return ( ....
)}
就我而言,我试图在 Windows 上使用 mdbreact。虽然它已安装,但我收到了上述错误。我不得不重新安装它,一切都很好。曾经两次用 antd Library 发生在我身上
如果您使用的是 mobx,并且您的功能组件包装在 mobx observer
函数中,也会发生此错误。如果是这种情况,请确保您使用的是 mobx-react
6.0.0 或更高版本。旧版本会将您的功能组件转换为隐藏的类,并且所有挂钩都将因此错误而失败。
在我的情况下,我从两个项目中删除了 package-lock.json
和 node_modules
并再次重新安装,现在工作正常。
// project structure
root project
- package-lock.json
- package.json // all dependencies are installed here
- node_modules
-- second project
-- package-lock.json
-- package.json
"dependencies": {
"react": "file:../node_modules/react",
"react-dom": "file:../node_modules/react-dom",
"react-scripts": "file:../node_modules/react-scripts"
},
-- node_modules
不知道是什么首先导致了这个问题,因为这发生在我之前并且做了与上面相同的步骤,并且问题得到了解决。
我遇到了类似的问题,但是我的情况有点极端。
接受的答案应该适用于大多数人,但对于在使用 Radium 的现有反应代码中使用反应钩子的其他任何人,请注意,如果您使用镭,钩子将无法工作,如果没有变通方法。
就我而言,我正在像这样导出我的组件:
// This is pseudocode
const MyComponent = props => {
const [hookValue, setHookValue] = useState(0);
return (
// Use the hook here somehow
)
}
export default Radium(MyComponent)
从 export
中删除该 Radium
包装器解决了我的问题。如果您需要使用 Radium,使用类组件及其生命周期函数可能是更简单的解决方案。
希望这至少可以帮助另一个人。
如果您的前端工作位于其自己的文件夹中,您可能需要在该文件夹中安装 @material-ui/core @material-ui/icons,而不是在后端文件夹中。
npm i @material-ui/core @material-ui/icons
如果上述所有方法都不起作用,特别是如果具有大尺寸依赖性(如我的情况),则构建和加载都需要至少 15 秒,因此延迟似乎给出了错误消息“无效的钩子调用”。所以你可以做的是在测试之前给一些时间来确保构建完成。
发现此错误:找到解决方案。
出于某种原因,我的标签上有 2 个 onClick
属性。小心使用您或某人的自定义组件,可能其中一些已经具有 onClick
属性。
当您使用依赖项而不安装它时也会发生这种情况。当我从“@material-ui/icons/”调用 MenuIcon 时发生在我身上,而该项目中缺少该菜单图标。
这是为我解决的问题。我的组件文件夹以及它所属的项目的根目录中有文件夹 node_modules 和文件 package.json 和 package-lock.json。我从它们不属于的地方删除了它们。不要问我做了什么把它们放在那里,我一定是从错误的位置做了一个 npm 的东西。
就我而言,我在 package-json 中所做的更改会导致问题。
npm install react-redux
解决这个问题
如果您使用的是 react-router-dom,请确保在钩子中调用 useHistory()。
您可以检查您的路线。如果您在 Route(
注意导入问题-对我来说,错误是关于组件和子组件的导入/自动导入失败。与功能类与类组件无关。
这很容易发生,因为 VS 代码自动导入可以指定不起作用的路径。
如果使用 import { MyComponent } 并在组件中使用 export default ,则导入应该说 import MyComponent
如果某些组件在其文件夹中使用 index.js 作为路径的快照,而其他不是导入的组件可能会中断。在这里,自动导入再次可能会导致问题,因为它将所有组件合并到与来自“../../common”的 {TextComponent, ButtonComponent, ListComponent} 相同的文件夹中
尝试注释掉文件中给出错误的一些组件,您可以测试这是否是问题所在。
就我而言,问题是我 cd 到了错误的目录来进行我的 npm 安装。我刚刚在正确的目录中重新安装了库,它工作正常!
我在处理自定义 node_module
并使用 npm link
在 cra
(创建反应应用程序)中进行测试时遇到了同样的问题。
我发现在我的自定义 node package
中,我必须添加一个 peerDependencies
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0"
},
将其添加到我的 package.json
中后,我然后 re-built
我的自定义包。然后在CRA
中,我吹走node_modules
,重新npm install
,重新做npm link <package>
,然后启动项目。
修复了一切!
我的错误在于最后的导出,我有以下内容:
https://i.stack.imgur.com/fh4TN.png
我应该删除括号:
https://i.stack.imgur.com/yTOfr.png
cra
处理应用程序,我永远不会看到此错误消息。只需在两个项目上运行npm i
,然后再次运行npm link
,就可以了。