Я хочу показать некоторые записи в таблице с помощью React, но я получил эту ошибку:
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.info("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;



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


React linter принимает все методы, начинающиеся с use, поскольку хуки и хуки не работают внутри классов. переименовав const useStyles во что-нибудь еще, что не начинается с use, как const myStyles, вы готовы к работе.
Обновлять:
makeStyles — это хук API, и вы не можете использовать его внутри классов. вы можете использовать API стилизованных компонентов. см. здесь
Есть ли какие-либо документы, подтверждающие, что это правда?
да ты прав. makeStyles — это API-интерфейс, и вы не можете использовать его внутри классов. см. здесь
Вы можете вызывать хуки только из функций React. Подробнее здесь.
Просто преобразуйте компонент класса 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.info(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(data), разрешения должны иметь данные, верно? иначе когда надбавки есть данные?
да. После вызова setAllowances(data). setAllowances работает как this.setState({allowances: data})
Я был немного сбит с толку, после вызова setAllowances(data) я попробовал console.info("data",data); и у этого есть 3 записи, но если я попытаюсь использовать console.info("разрешение",разрешения); это ничего не записывает. Могу я узнать почему? Вы можете попробовать в своем примере кода.
Причина setAllowances асинхронна, как и this.setState. поэтому вы регистрируете allowances после setAllowances, он регистрирует old allowances.
Где, по авторскому пособию, вызывали хуки?
@Thuy Это звонок React.useContext здесь github.com/mui-org/material-ui/blob/…
Вы можете преобразовать компонент класса в хуки, но в Material v4 есть withStyles HOC. https://material-ui.com/styles/basics/#higher-order-component-api Используя этот HOC, вы можете сохранить свой код без изменений.
Вчера я сократил код (только что добавил <Provider store = {store}>) и все еще сталкивался с этой проблемой недопустимого вызова хука. Это заставило меня внезапно осознать, какую ошибку я совершил: я не установил программное обеспечение react-redux в эту папку.
Я установил это программное обеспечение в другую папку проекта, поэтому я не знал, что это также необходимо. После установки ошибка исчезла.
Как ты это починил? Я также использую игровую консоль провайдера, которая сообщила мне, что есть некоторые ошибки в вызове хука.
Я только начал использовать хуки и получил указанное выше предупреждение, когда вызывал 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]);
Надеюсь кому-то будет полезно!
Если все вышеперечисленное не работает, особенно при наличии зависимости большого размера (как в моем случае), и сборка, и загрузка занимали как минимум 15 секунд, поэтому кажется, что задержка выдала ложное сообщение «Неверный вызов ловушки». Так что вы можете дать некоторое время, чтобы убедиться, что сборка завершена перед тестированием.
Вы можете использовать «экспорт по умолчанию», вызвав функцию стрелки, которая возвращает свой React.Component, передавая его через свойства объекта класса MaterialUI, которые, в свою очередь, будут использоваться в рендеринге компонента ().
class AllowanceClass extends Component{
...
render() {
const classes = this.props.classes;
...
}
}
export default () => {
const classes = useStyles();
return (
<AllowanceClass classes = {classes} />
)
}
Поймал эту ошибку: найдено решение.
По какой-то причине в моем теге было 2 атрибута onClick.
Будьте осторожны с использованием ваших или чьих-либо пользовательских компонентов, возможно, некоторые из них уже имеют атрибут onClick.
Для меня ошибка вызывала функцию useState за пределами функции, экспортируемой по умолчанию.
В моем случае я пытался использовать mdbreact для Windows. Хотя он установлен, но я получаю вышеуказанную ошибку. Пришлось переустанавливать и все ок. Это случилось со мной раз два с библиотекой antd
Это тоже помогло мне, я просто решил использовать другую библиотеку пользовательского интерфейса
У меня была эта проблема, когда я использовал npm link для установки моей локальной библиотеки, которую я создал с помощью cra. Я нашел ответ здесь. Что буквально говорит:
This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming 'myapp' and 'mylib' are sibling folders, one possible fix is to run 'npm link ../myapp/node_modules/react' from 'mylib'. This should make the library use the application’s React copy.
Таким образом, запустив команду: npm link <path_to_local_library>/node_modules/react, например. в моем случае npm link ../../libraries/core/decipher/node_modules/react из каталога проекта решил проблему.
Спасибо друг! ты спас мой день! Всем, кто использует локальные пакеты по ссылке npm/yarn, следуйте этому!
Это сработало для меня. Это была моя точная проблема.
тогда это вызовет ошибку при публикации в npm, верно? или, может быть, нет, поскольку он связан, на моей машине он будет использовать ответ из ссылки, а после публикации он будет использовать свой собственный. ?
Работая над приложением с cra, связанным с локальной библиотекой в течение длительного времени, я никогда не видел это сообщение об ошибке. Просто запустите npm i в обоих проектах, затем снова npm link, и все в порядке.
У меня ушло 8 часов на эту проблему и попытку закончить функцию по-другому. Большое спасибо
Это исправлено локально. Но после публикации моего пакета эта ошибка возвращается. Любой?
Я столкнулся с этой же проблемой, работая над пользовательским 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>, а затем начал проект. Все исправил!
Мое дело....РЕШЕНИЕ в КРЮКАХ
const [cep, setCep] = useState('');
const mounted = useRef(false);
useEffect(() => {
if (mounted.current) {
fetchAPI();
} else {
mounted.current = true;
}
}, [cep]);
const setParams = (_cep) => {
if (cep !== _cep || cep === '') {
setCep(_cep);
}
};
Эта ошибка также может возникнуть, если вы ошиблись, объявив useDispatch из react-redux неправильным образом:
когда вы идете: const dispatch = useDispatch вместо: const dispatch = useDispatch(); (т.е. не забудьте добавить скобки)
Для меня это были пакеты reduxreact-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);
происходит также, когда вы используете зависимость без ее установки. случилось со мной, когда я вызвал MenuIcon из '@material-ui/icons/', когда он отсутствовал в проекте.
Различные версии реакции между моими общими библиотеками, казалось, были проблемой (16 и 17), обе изменились на 16.
Эта ошибка также может возникнуть, если вы используете mobx, и ваш функциональный компонент заключен в функцию mobx observer. В этом случае убедитесь, что вы используете mobx-react версию 6.0.0 или выше. Старые версии будут конвертировать ваш функциональный компонент в класс под прикрытием, и все хуки не будут работать с этой ошибкой.
Смотрите ответ здесь: React Hooks Mobx: неверный вызов ловушки. Хуки можно вызывать только внутри тела функционального компонента.
добавьте это в свой 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
Это сработало для меня! Большое спасибо
Всем, кто может искать БЫСТРОЕ решение этой проблемы:
Возможно, вы нарушаете правила хуков. Чтобы решить эту проблему, переместите:
?const [x, setX] = useState(0);
на ВЕРХНИЙ УРОВЕНЬ вызывающей его функции, а не вне функции.
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
Халед Рахиси, ссылка на решение приветствуется, но, пожалуйста, убедитесь, что ваш ответ полезен и без нее: добавить контекст вокруг ссылки, чтобы ваши коллеги-пользователи имели некоторое представление о том, что это такое и почему оно существует, а затем процитируйте наиболее важную часть страницы, на которой вы находитесь. ссылка на в случае, если целевая страница недоступна. Ответы, которые представляют собой не более чем ссылку, могут быть удалены.
Я отвечаю на этот вопрос, причина моей ошибки в том, что я разрабатываю проект 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, даже если они имеют одинаковые версии. но я не могу проверить свою догадку.
похоже, вам нужно настроить peer dependencies в вашем package.json nodejs.org/es/blog/npm/peer-dependencies
Вот что исправило это для меня. У меня была папка node_modules и файлы package.json и package-lock.json в папке моих компонентов, а также в корне моего проекта, где она принадлежит. Я удалил их оттуда, где им не место. Не спрашивайте меня, что я сделал, чтобы поместить их туда, я, должно быть, сделал npm что-то не в том месте.
В моем случае я передал имя компонента в реквизите FlatList вместо функции. Раньше он работал, так как мой компонент был функциональным, но когда я добавил в него хуки, он не работал.
До:
<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>
}
/>
У меня была такая же проблема, и как только я нашел решение, я смог найти ваш ответ. Голосование за повышение!
в моем случае я удалил 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
Не уверен, что вызвало проблему в первую очередь, так как это случалось со мной раньше, и я делал те же шаги, что и выше, и проблема была решена.
В моем случае изменения, которые я сделал в package-json, вызывают проблемы.
npm install react-redux
исправить это
Если вы используете react-router-dom, обязательно вызовите useHistory() внутри хука.
Вы можете проверить свои маршруты. Если вы используете рендеринг вместо компонента в Route(<Route path="/testpath" render = {(props)=><Test {...props} />} />) поэтому вы правильно назвали свой компонент в функции стрелки, передав ей соответствующие реквизиты.
Помните о проблемах с импортом. Для меня ошибка заключалась в сбое импорта/автоматического импорта компонентов и дочерних компонентов. Не имел ничего общего с функциональными классами и компонентами класса.
{ MyComponent } используется и export default используется в компоненте, импорт должен сказать import MyComponent{TextComponent, ButtonComponent, ListComponent} from '../../common'Попробуйте закомментировать некоторые компоненты в файле, который вызывает ошибку, и вы сможете проверить, не в этом ли проблема.
Когда вы столкнетесь с этой проблемой, вам просто нужно переустановить этот «npm install react-bootstrap@next [email protected]», после чего ваша ошибка будет устранена.
Это на самом деле не отвечает на вопрос. Если у вас есть другой вопрос, вы можете задать его, нажав Задать вопрос. Чтобы получать уведомления, когда на этот вопрос будут получены новые ответы, вы можете следить за этим вопросом. Как только у вас будет достаточно репутация, вы также можете добавить награду привлечь больше внимания к этому вопросу.
В моем случае именно эта единственная строка кода, которая была в моем 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 ( ....
)}
В моем случае проблема заключалась в том, что я перешел в неправильный каталог для установки npm. Я просто переустановил библиотеки в правильный каталог, и все заработало!
Я столкнулся с аналогичной проблемой, однако моя ситуация была чем-то вроде граничного случая.
Принятый ответ должен работать для большинства людей, но для всех, кто использует реагирующие хуки в существующем реагирующем коде, который использует Радий, обратите внимание, что хуки не будут работать без обходных путей, если вы используете радий.
В моем случае я экспортировал свой компонент так:
// This is pseudocode
const MyComponent = props => {
const [hookValue, setHookValue] = useState(0);
return (
// Use the hook here somehow
)
}
export default Radium(MyComponent)
Удаление этой оболочки Radium из export решило мою проблему. Если вы нужно используете Radium, более простым решением может быть обращение к компонентам класса и их функциям жизненного цикла.
Надеюсь, это поможет хотя бы еще одному человеку.
Я столкнулся с этой же проблемой, работая над пользовательским 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>, а затем начал проект.
Все исправил!
изменил стили использования на mystyles, но ошибка все еще возникает.