Я хочу показать несколько записей в таблице с помощью React, но получаю такую ​​ошибку:

Неверный вызов трубки. Крючки можно вызывать только внутри корпуса функциональная составляющая. Это могло произойти по одному из следующих причины:

  1. Возможно, у вас несовпадающие версии React и средства визуализации (например, React DOM)
  2. Возможно, вы нарушаете правила хуков
  3. У вас может быть несколько копий React в одном приложении. См. Советы по отладке и исправьте эту проблему.
импорт React, {
  Компонент
} от 'реагировать';
Импортировать {
  makeStyles
} из '@ material-ui / core / styles';
импортировать таблицу из '@ material-ui / core / Table';
импортировать TableBody из '@ material-ui / core / TableBody';
импортировать TableCell из '@ material-ui / core / TableCell';
импортировать TableHead из '@ material-ui / core / TableHead';
импортировать TableRow из '@ material-ui / core / TableRow';
импортировать бумагу из '@ material-ui / core / Paper';

const useStyles = makeStyles (theme => ({
  корень: {
    ширина: '100%',
    marginTop: theme.spacing (3),
    overflowX: 'авто',
  },
  Таблица: {
    minWidth: 650,
  },
}));

надбавка за класс расширяет Компонент {
  constructor () {
    супер();
    this.state = {
      надбавки: [],
    };

  }

  componentWillMount () {
    fetch ('http://127.0.0.1: 8000 / надбавки')
      .then (data => {

        вернуть данные.json ();

      }). then (data => {

        this.setState ({
          пособия: данные
        });

        console.log («состояние допуска», this.state.allowances);
      })

  }



  оказывать() {
    константные классы = useStyles ();
    возврат (<
      Paper className = {
        classes.root
      }>
      <
      Table className = {
        classes.table
      }>
      <
      TableHead>
      <
      TableRow>
      <
      TableCell> Разрешить ID  <
      TableCell align = "right"> Описание  <
      TableCell align = "right"> Разрешить сумму  <
      TableCell align = "right"> AllowType 

      <
      / TableRow> <
      / TableHead> <
      TableBody> {
        this.state.allowances.map (row => (<
          Ключ TableRow = {
            row.id
          }>
          <
          Компонент TableCell = "th"
          scope = "row"> {
            row.AllowID
          } <
          / TableCell> <
          TableCell align = "right"> {
            row.AllowDesc
          }  <
          TableCell align = "right"> {
            row.AllowAmt
          }  <
          TableCell align = "right"> {
            row.AllowType
          }  <
          / TableRow>
        ))
      } <
      / TableBody> <
      / Таблица> <
      / Бумага>
    );
  }

}

разрешение на экспорт по умолчанию;

Ответы (28)

Вы можете вызывать хуки только из функций React. Подробнее здесь.

Just convert the Allowance class component to a functional component.

Working CodeSandbox demo.

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;

Реагирующий линтер предполагает, что все методы, начинающиеся с , используют, поскольку хуки и хуки не работают внутри классов. переименовав const useStyles во что-либо еще, что не начинается с , используйте, например const myStyles, вы готовы.

Update:

makeStyles is hook api and you can't use that inside classes. you can use styled components API. see here

Я только начал использовать хуки и получил указанное выше предупреждение, когда вызывал useEffect внутри функции:

Then I have to move the useEffect outside of the function as belows:

 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]);

Hope it will be helpful to someone !

Проблемой казались разные версии реакции между моими разделяемыми библиотеками (16 и 17), обе изменились на 16.

Эта ошибка также может возникнуть, если вы ошиблись, объявив useDispatch из response-redux неправильно: когда вы идете:
const dispatch = useDispatch вместо:
const dispatch = useDispatch (); (т.е. не забудьте добавить круглые скобки)

добавьте это в свой package.json

"peerDependencies": {
   "react": ">=16.8.0",
   "react-dom": ">=16.8.0"
}

source:https://robkendal.co.uk/blog/2019-12-22-solving-react-hooks-invalid-hook-call-warning

У меня возникла эта проблема, когда я использовал 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.

Thus, running the command: npm link /node_modules/react, eg. in my case npm link ../../libraries/core/decipher/node_modules/react from the project directory has fixed the issue.

В моем случае изменения, которые я сделал в package-json, вызывают проблемы.

npm install react-redux

fix that

в моем случае я удалил 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


Not sure what caused the issue in the first place, as this happened to me before and did same steps as above, and issue was resolved.

Всем, кто ищет БЫСТРОЕ решение этой проблемы:

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 (
      

{x}

); }

👍 https://reactjs.org/warnings/invalid-hook-call-warning.html

В моем случае я пытался использовать mdbreact в Windows. Хотя он установлен, но я получал указанную выше ошибку. Пришлось переустановить, и все было нормально. Так случилось со мной раз два с библиотекой antd

Мой случай .... РЕШЕНИЕ КРЮЧКИ

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);
    }
};

Вы можете использовать «экспорт по умолчанию», вызвав функцию стрелки, которая возвращает ее React.Component, передав ее через свойства объекта класса MaterialUI, которые, в свою очередь, будут использоваться в компоненте render ().

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}

export default () => {
    const classes = useStyles();
    return (
        
    )
}

Когда вы столкнетесь с этой проблемой, вам просто нужно переустановить эту «npm install react-bootstrap@next bootstrap@5.1.0», и ваша ошибка будет устранена.

Для меня ошибка заключалась в вызове функции useState вне экспортированной функции по умолчанию

также случается, когда вы используете зависимость, не устанавливая ее. случилось со мной, когда я вызвал MenuIcon из '@ material-ui / icons /', когда он отсутствовал в проекте.

Если вы используете response-router-dom, обязательно вызовите useHistory () внутри ловушки.

Вы можете проверить свои маршруты. Если вы используете рендеринг вместо компонента в Route ( } />) поэтому вы правильно вызвали свой компонент в стрелочной функции, передав ему соответствующие реквизиты.

Если все вышеперечисленное не работает, особенно при большой зависимости от размера (как в моем случае), и сборка, и загрузка занимали минимум 15 секунд, поэтому кажется, что задержка дала ложное сообщение «Неверный вызов ловушки. " Итак, что вы можете сделать, это дать некоторое время, чтобы убедиться, что сборка завершена перед тестированием.

Вот что у меня исправило. У меня была папка node_modules и файлы package.json и package-lock.json в папке моих компонентов, а также в корне моего проекта, которому он принадлежит. Я удалил их там, где им не место. Не спрашивайте меня, что я сделал, чтобы поместить их туда, должно быть, я сделал что-то npm из неправильного места.

Выявлена ​​эта ошибка: найдено решение.

For some reason, there were 2 onClick attributes on my tag. Be careful with using your or somebodies' custom components, maybe some of them already have onClick attribute.

Вчера я сократил код (только что добавил ), но по-прежнему столкнулся с этой проблемой недопустимого вызова ловушки. Это заставило меня внезапно понять, какую ошибку я сделал: я не установил программу response-redux в эту папку.

I had installed this software in the other project folder, so I didn't realize this one also needed it. After installing it, the error is gone.

Эта ошибка также может возникнуть, если вы используете mobx, а ваш функциональный компонент заключен в функцию mobx наблюдатель. В этом случае убедитесь, что вы используете mobx-react версии 6.0.0 или выше. Более старые версии преобразуют ваш функциональный компонент в класс, скрытый под покровом, и все перехватчики завершатся с ошибкой.

See answer here: React Hooks Mobx: invalid hook call. Hooks can only be called inside of the body of a function component

дополняя следующий комментарий

For those who use redux:

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}
    
const COMAllowanceClass = (props) =>
{
    const classes = useStyles();
    return ();
};

const mapStateToProps = ({ InfoReducer }) => ({
    token: InfoReducer.token,
    user: InfoReducer.user,
    error: InfoReducer.error
});
export default connect(mapStateToProps, { actions })(COMAllowanceClass);

Я отвечаю на этот вопрос. Причина моей ошибки в том, что я разрабатываю проект A и связываю другой проект B с A, но у A есть пакет React, а у B также есть пакет React, это одна и та же версия (16.13). но это вызывает вопрос, я установил файл, означает webpack.config.js, например:

alias: {
  'react': path.join(path.resolve(__dirname), '../node_modules/react'),
},

set B React package resolve to A React package,I guess reason is that a project can not has two or more React package, even if they are the same versions. but I can not verify my guess.

Остерегайтесь проблем с импортом. Для меня ошибка заключалась в сбое импорта / автоматического импорта компонентов и дочерних компонентов. Не имело ничего общего с функциональными классами и компонентами класса.

  • This is prone to happen as VS code auto importing can specify paths that are not working.
  • if import { MyComponent } is used and export default used in the component the import should say import MyComponent
  • If some Components use index.js inside their folder, as a shotcut for the path, and others not the imports might break. Here again the auto import can cause problems as it merges all components form same folder as this {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.

В моем случае я передавал имя компонента в FlatListrenderItem prop вместо функции. Раньше он работал, так как мой компонент был функциональным, но когда я добавил в него хуки, он вышел из строя.

Before:

    }
        keyExtractor={member => member.name.split(' ').join('')}
        ListEmptyComponent={
          
            No Data: Click above button to fetch data
          
        }
      />

After:

     }
        keyExtractor={member => member.name.split(' ').join('')}
        ListEmptyComponent={
          
            No Data: Click above button to fetch data
          
        }
      />

Вы можете преобразовать компонент класса в хуки, но в Material v4 есть withStyles HOC. https://material-ui.com/styles/basics/#higher-order-component-api Используя этот HOC, вы можете сохранить свой код без изменений.

2022 WebDevInsider