反应“错误:超过最大更新深度。”带有功能组件和钩子

Posted

技术标签:

【中文标题】反应“错误:超过最大更新深度。”带有功能组件和钩子【英文标题】:React 'Error: Maximum update depth exceeded.' with functional component and hooks 【发布时间】:2020-09-23 21:27:14 【问题描述】:

我收到以下错误:

Error: Maximum update depth exceeded.

有了这个组件:

const UsersPage: React.FunctionComponent<UsersPageProps> = (
  location,
  history,
  match,
): JSX.Element => 
  const dispatch = useDispatch();
  const  search  = location;

  const query = parseInt(location.search, 10);
  const [currentPage, setCurrentPage] = useState<number>(
    isNaN(query) || query < 0 ? 0 : query
  );

  const users = useSelector((state: any) => state.manageUsers.users.results);
  const isLoading = useSelector((state: any) => state.manageUsers.usersLoaded);
  const totalPages = useSelector(
    (state: any) => state.manageUsers.users.totalPages
  );
  const handlePaginationChange = (
    event: React.ChangeEvent<any>,
    pageNumber: number
  ): void => 
    history.push(`$match.path?page=$pageNumber ?? 0`);
    setCurrentPage(pageNumber ?? 0);
  ;

  const handleAddUserOnClick = () =>
    dispatch(manageUsersSetNewUserAndNavigate());
  const handleEditOnClick = (id) =>
    dispatch(manageUsersSetActiveEditUserAndNavigate(id));

  useEffect(() => 
    dispatch(manageUsersLoadUsers(currentPage));
  , [currentPage]);

  return (
    <section className="users page">
      !isLoading && <SectionLoaderWithMessage message="Loading users..." />
      isLoading && (
        <React.Fragment>
          <Toolbar disableGutters=true>
            <Title flex=1>Manage Users</Title>

            <Button
              variant="contained"
              color="secondary"
              onClick=handleAddUserOnClick
              startIcon=<AddCircle />
            >
              Add User
            </Button>
          </Toolbar>
          <TableContainer component=Paper>
            <Table aria-label="table">
              <TableHead>
                <TableRow style= backgroundColor: "white" >
                  <TableCell style= fontWeight: "bold", minWidth: 150 >
                    Email
                  </TableCell>
                  <TableCell style= fontWeight: "bold", minWidth: 150 >
                    Name
                  </TableCell>
                  <TableCell style= fontWeight: "bold", minWidth: 150 >
                    Surname
                  </TableCell>
                  <TableCell style= fontWeight: "bold", minWidth: 150 >
                    Firm
                  </TableCell>
                  <TableCell style= fontWeight: "bold", minWidth: 150 >
                    Type
                  </TableCell>
                  <TableCell style= fontWeight: "bold", minWidth: 150 >
                    Enabled
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                users.map((user, index) => (
                  <TableRow
                    key=`$user.id-$index`
                    onClick=() => handleEditOnClick(user.id)
                    hover
                  >
                    <TableCell>user.email</TableCell>
                    <TableCell>user.name</TableCell>
                    <TableCell>user.surname</TableCell>
                    <TableCell>user.firmName</TableCell>
                    <TableCell>user.type</TableCell>
                    <TableCell>`$user.enabled`</TableCell>
                  </TableRow>
                ))
              </TableBody>
            </Table>
            <ThemedTablePagination
              totalPages=totalPages
              pageNumber=currentPage
              onChange=handlePaginationChange
            />
          </TableContainer>
        </React.Fragment>
      )
    </section>
  );
;

export default UsersPage;

我在渲染中看不到任何更新状态以导致无限循环的地方。

【问题讨论】:

您是否尝试将其缩减为 minimal reproducible example? 我不确定,但我认为 useEffect 中的调度会重新渲染组件。所以当它重新渲染时,useEffect 会再调用一次,直到无限。 【参考方案1】:

函数handlePaginationChange应该在useEffect里面。

目前,每次调用 setCurrentPage 时,它都会重新渲染组件,该组件又会再次调用 handlePaginationChange 函数,因此再次调用 setCurrentPage 并且循环继续进行。

【讨论】:

您可以尝试在您当前的 useEffect() 中放置 console.count 吗?看看这是否被称为无限次

以上是关于反应“错误:超过最大更新深度。”带有功能组件和钩子的主要内容,如果未能解决你的问题,请参考以下文章

我从 React 得到一个错误:超过最大更新深度

React App登录错误:超过最大更新深度

超过最大更新深度 - React Js

React Typescript with hooks:最大更新深度超出错误

如何在反应中使用带有useState钩子的回调[重复]

加载页面时如何始终调用 onClick?错误:超过最大更新深度 [重复]