reactjs - 与之前使用自定义钩子(Hook)的渲染相比,渲染了更多的钩子(Hook)

标签 reactjs react-hooks material-ui

在我的组件中使用自定义 Hook 返回值时,我不断收到“渲染的 Hook 比之前渲染期间更多的 Hook ”错误

钩子(Hook)看起来像这样

import { useState, useEffect } from 'react';
import axios from 'axios';

const { REACT_APP_BASE_PATH } = process.env;

axios.defaults.baseURL = REACT_APP_BASE_PATH;

export const useAxios = (axiosParams, deps = []) => {
  const [response, setResponse] = useState({});
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(true);

  const fetchData = async (params) => {
    try {
      const result = await axios.request(params);
      setResponse(result.data);
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchData(axiosParams);
  }, [...deps]);

  return { response, error, loading };
};

export default { useAxios };

该组件如下所示:

import React from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Box, Button, Typography } from '@material-ui/core';
import CircularProgress from '@material-ui/core/CircularProgress';
import { useAxios } from '../../helpers/hooks';
import { accountsListColumns, renderItems } from '../../helpers/constants';
import useStyles from '../styles';

export const SingleAccountPage = () => {
  const { search } = useLocation();
  const history = useHistory();
  const classes = useStyles();

  const {
    response = [],
    error,
    loading,
  } = useAxios({
    method: 'GET',
    url: `/account/findOne${search}`,
  });

  if (loading) return <CircularProgress />;
  if (error) return <h1>{error}</h1>;

  return (
    <Box className={classes.singlePageWrapper}>
      <Box className={classes.singlePageHeader}>
        <Typography variant={'h4'}>Account: {response.id}</Typography>
        <Button
          variant={'contained'}
          onClick={() => history.goBack()}
          className={classes.singlePageBackButton}
        >
          Go back
        </Button>
      </Box>
      {renderItems(accountsListColumns, response)}
    </Box>
  );
};

所以基本上这两行由于某种原因导致了问题

  if (loading) return <CircularProgress />;
  if (error) return <h1>{error}</h1>;

将来,我想有条件地渲染错误并加载组件,但现在由于某种原因,这也不起作用。

在错误消息中,它说

index.js:1 Warning: React has detected a change in the order of Hooks called by SingleAccountPage. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks

   Previous render            Next render
   ------------------------------------------------------
1. useContext                 useContext
2. useContext                 useContext
3. useContext                 useContext
4. useDebugValue              useDebugValue
5. useContext                 useContext
6. useRef                     useRef
7. useRef                     useRef
8. useRef                     useRef
9. useMemo                    useMemo
10. useEffect                 useEffect
11. useEffect                 useEffect
12. useDebugValue             useDebugValue
13. useState                  useState
14. useState                  useState
15. useState                  useState
16. useEffect                 useEffect
17. undefined                 useContext
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

未捕获错误:渲染的钩子(Hook)比上次渲染期间更多。

你能帮我解决这个问题吗?

最佳答案

对此有一个非常简单的解决方法。将所有函数、钩子(Hook)移动到 return 语句上方的任何地方。这样所有的钩子(Hook)都会在 return 语句之前呈现。这可能对性能不利,但目前确实是一种解决方法。

关于reactjs - 与之前使用自定义钩子(Hook)的渲染相比,渲染了更多的钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69054689/

相关文章:

jquery - 使用 jQuery 插件来更改 React 中的 DOM

node.js - package.json中的首页条目出现错误

reactjs - useEffect 导致无限循环

javascript - 使用 React : Uncaught TypeError: Cannot read property 'clientWidth' of null 自定义鼠标光标

javascript - _react.default.useContext 不是函数

javascript - 如何在 typescript 中预先输入 React 元素数组

javascript - 如何向 Material-UI 的 AppBar 组件添加多个元素?

node.js - 使用 React 实现 Spotify API

javascript - React Nested Router仅更改url,但不渲染页面

javascript - 使用动态导入加载 React 钩子(Hook)?