我想用React在一个表中显示一些记录,但我得到了这个错误:
无效的钩子调用。类的主体内部只能调用钩子
功能组件。这可能发生在以下情况之一
原因:
React和渲染器的版本可能不匹配(比如React DOM)
你可能违反了胡克斯的规矩
你可能在同一个应用程序中有多个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;
我遇到这个问题,我的错误原因是我开发项目A,我把另一个项目B链接到A,但是A有React包,B也有React包,它们是同一个版本(16.13)。
但是这引起了问题,我设置文件的意思是webpack.config.js,像这样:
alias: {
'react': path.join(path.resolve(__dirname), '../node_modules/react'),
},
将B React包解析为A React包,我猜原因是一个项目不能有两个或两个以上的React包,即使它们是相同的版本。但我无法证实我的猜测。
在我的例子中,我在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>
}
/>
在我的情况下,我拆除了包装锁。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
不确定是什么原因导致了这个问题,因为这发生在我之前,并采取了与上面相同的步骤,问题已经解决了。
注意导入问题——对我来说,错误是关于组件和子组件的导入/自动导入失败。与函数类与类组件无关。
这很容易发生,因为VS code自动导入可以指定的路径不能工作。
如果在组件中使用了import {MyComponent}和export default,则导入应该说import MyComponent
如果某些组件在其文件夹中使用index.js作为路径的shotcut,而其他组件则不使用,则导入可能会中断。在这里,自动导入可能会导致问题,因为它合并了来自'../../common'的{TextComponent, ButtonComponent, ListComponent}相同文件夹中的所有组件
尝试注释掉文件中给出错误的一些组件,您可以测试这是否是问题所在。
在我的例子中,这只是我的App.js上的这一行代码,导致了这个问题,让我在调试上浪费了10个小时。React Native和Expo不能告诉我这一点。我在StackOverflow和github上做了所有的事情,甚至在react页面上应该解决这个问题,但问题仍然存在。为了找到罪魁祸首,我不得不一点一点地把我的代码拆开
**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 ( ....
)}
我在一个自定义node_module上工作时遇到了同样的问题,并在cra(创建react应用程序)中使用npm link进行测试。
我发现在我的自定义节点包中,我必须添加一个peerDependencies
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0"
},
我把它加到我的包里。json,然后重新构建我的自定义包。
然后在CRA,我吹走node_modules, re npm install, re -do npm link <package>,然后启动项目。
固定的一切!
当我在类组件中使用useLocation钩子时,我也有同样的问题
错误:
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>;
}
}
解决方案:我已经将类组件转换为功能组件,然后问题解决
import React from "react";
import { useLocation } from "react-router-dom";
const ShowTheLocation = () => {
const location = useLocation();
return <div>You are now at {location.pathname}</div>;
}
我用的是电子。
我测试了上面所有的答案,甚至深入到基础应用程序,发现这种情况仍然存在。
事实证明,如果你正在使用electron(在我的情况下,特别是expo-electron),它有它自己的webpack配置,并且你需要在webpack配置中白名单redux。我的electronic -webpack.js文件是这样的:
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"],
});
对我来说,这个问题是由webpack设置解决引起的。Symlinks (https://webpack.js.org/configuration/resolve/#resolvesymlinks),设置为false:
resolve: {
symlinks: false,
因此,从另一个包到React的符号链接无法解析,并导致无效钩子调用错误。
将它设置为true或简单地省略它(显然它默认为true)解决了问题:
resolve: {
symlinks: true,