🚑 fix: resolve React hooks order violation in pagination components
Fix "Rendered fewer hooks than expected" error caused by conditional hook calls in createCardProPagination function. The issue occurred when paginationArea was commented out, breaking React's hooks rules. **Problem:** - createCardProPagination() internally called useIsMobile() hook - When paginationArea was disabled, the hook was not called - This violated React's rule that hooks must be called in the same order on every render **Solution:** - Refactor createCardProPagination to accept isMobile as a parameter - Move useIsMobile() hook calls to component level - Ensure consistent hook call order regardless of pagination usage **Changes:** - Update createCardProPagination function to accept isMobile parameter - Add useIsMobile hook calls to all table components - Pass isMobile parameter to createCardProPagination in all usage locations **Files modified:** - web/src/helpers/utils.js - web/src/components/table/channels/index.jsx - web/src/components/table/redemptions/index.jsx - web/src/components/table/usage-logs/index.jsx - web/src/components/table/tokens/index.jsx - web/src/components/table/users/index.jsx - web/src/components/table/mj-logs/index.jsx - web/src/components/table/task-logs/index.jsx Fixes critical runtime error and ensures stable pagination behavior across all table components.
This commit is contained in:
@@ -24,6 +24,7 @@ import ChannelsActions from './ChannelsActions.jsx';
|
||||
import ChannelsFilters from './ChannelsFilters.jsx';
|
||||
import ChannelsTabs from './ChannelsTabs.jsx';
|
||||
import { useChannelsData } from '../../../hooks/channels/useChannelsData.js';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile.js';
|
||||
import BatchTagModal from './modals/BatchTagModal.jsx';
|
||||
import ModelTestModal from './modals/ModelTestModal.jsx';
|
||||
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
|
||||
@@ -33,6 +34,7 @@ import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const ChannelsPage = () => {
|
||||
const channelsData = useChannelsData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -65,6 +67,7 @@ const ChannelsPage = () => {
|
||||
total: channelsData.channelCount,
|
||||
onPageChange: channelsData.handlePageChange,
|
||||
onPageSizeChange: channelsData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={channelsData.t}
|
||||
>
|
||||
|
||||
@@ -26,10 +26,12 @@ import MjLogsFilters from './MjLogsFilters.jsx';
|
||||
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
|
||||
import ContentModal from './modals/ContentModal.jsx';
|
||||
import { useMjLogsData } from '../../../hooks/mj-logs/useMjLogsData.js';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile.js';
|
||||
import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const MjLogsPage = () => {
|
||||
const mjLogsData = useMjLogsData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -48,6 +50,7 @@ const MjLogsPage = () => {
|
||||
total: mjLogsData.logCount,
|
||||
onPageChange: mjLogsData.handlePageChange,
|
||||
onPageSizeChange: mjLogsData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={mjLogsData.t}
|
||||
>
|
||||
|
||||
@@ -25,10 +25,12 @@ import RedemptionsFilters from './RedemptionsFilters.jsx';
|
||||
import RedemptionsDescription from './RedemptionsDescription.jsx';
|
||||
import EditRedemptionModal from './modals/EditRedemptionModal';
|
||||
import { useRedemptionsData } from '../../../hooks/redemptions/useRedemptionsData';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile';
|
||||
import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const RedemptionsPage = () => {
|
||||
const redemptionsData = useRedemptionsData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const {
|
||||
// Edit state
|
||||
@@ -106,6 +108,7 @@ const RedemptionsPage = () => {
|
||||
total: redemptionsData.tokenCount,
|
||||
onPageChange: redemptionsData.handlePageChange,
|
||||
onPageSizeChange: redemptionsData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={t}
|
||||
>
|
||||
|
||||
@@ -26,10 +26,12 @@ import TaskLogsFilters from './TaskLogsFilters.jsx';
|
||||
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
|
||||
import ContentModal from './modals/ContentModal.jsx';
|
||||
import { useTaskLogsData } from '../../../hooks/task-logs/useTaskLogsData.js';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile.js';
|
||||
import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const TaskLogsPage = () => {
|
||||
const taskLogsData = useTaskLogsData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -48,6 +50,7 @@ const TaskLogsPage = () => {
|
||||
total: taskLogsData.logCount,
|
||||
onPageChange: taskLogsData.handlePageChange,
|
||||
onPageSizeChange: taskLogsData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={taskLogsData.t}
|
||||
>
|
||||
|
||||
@@ -25,10 +25,12 @@ import TokensFilters from './TokensFilters.jsx';
|
||||
import TokensDescription from './TokensDescription.jsx';
|
||||
import EditTokenModal from './modals/EditTokenModal';
|
||||
import { useTokensData } from '../../../hooks/tokens/useTokensData';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile';
|
||||
import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const TokensPage = () => {
|
||||
const tokensData = useTokensData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const {
|
||||
// Edit state
|
||||
@@ -108,6 +110,7 @@ const TokensPage = () => {
|
||||
total: tokensData.tokenCount,
|
||||
onPageChange: tokensData.handlePageChange,
|
||||
onPageSizeChange: tokensData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={t}
|
||||
>
|
||||
|
||||
@@ -25,10 +25,12 @@ import LogsFilters from './UsageLogsFilters.jsx';
|
||||
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
|
||||
import UserInfoModal from './modals/UserInfoModal.jsx';
|
||||
import { useLogsData } from '../../../hooks/usage-logs/useUsageLogsData.js';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile.js';
|
||||
import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const LogsPage = () => {
|
||||
const logsData = useLogsData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -47,6 +49,7 @@ const LogsPage = () => {
|
||||
total: logsData.logCount,
|
||||
onPageChange: logsData.handlePageChange,
|
||||
onPageSizeChange: logsData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={logsData.t}
|
||||
>
|
||||
|
||||
@@ -26,10 +26,12 @@ import UsersDescription from './UsersDescription.jsx';
|
||||
import AddUserModal from './modals/AddUserModal.jsx';
|
||||
import EditUserModal from './modals/EditUserModal.jsx';
|
||||
import { useUsersData } from '../../../hooks/users/useUsersData';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile';
|
||||
import { createCardProPagination } from '../../../helpers/utils';
|
||||
|
||||
const UsersPage = () => {
|
||||
const usersData = useUsersData();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const {
|
||||
// Modal state
|
||||
@@ -111,6 +113,7 @@ const UsersPage = () => {
|
||||
total: usersData.userCount,
|
||||
onPageChange: usersData.handlePageChange,
|
||||
onPageSizeChange: usersData.handlePageSizeChange,
|
||||
isMobile: isMobile,
|
||||
})}
|
||||
t={t}
|
||||
>
|
||||
|
||||
@@ -24,7 +24,6 @@ import { toast } from 'react-toastify';
|
||||
import { THINK_TAG_REGEX, MESSAGE_ROLES } from '../constants/playground.constants';
|
||||
import { TABLE_COMPACT_MODES_KEY } from '../constants';
|
||||
import { MOBILE_BREAKPOINT } from '../hooks/common/useIsMobile.js';
|
||||
import { useIsMobile } from '../hooks/common/useIsMobile.js';
|
||||
|
||||
const HTMLToastContent = ({ htmlContent }) => {
|
||||
return <div dangerouslySetInnerHTML={{ __html: htmlContent }} />;
|
||||
@@ -570,7 +569,7 @@ export const modelSelectFilter = (input, option) => {
|
||||
};
|
||||
|
||||
// -------------------------------
|
||||
// CardPro 分页配置组件
|
||||
// CardPro 分页配置函数
|
||||
// 用于创建 CardPro 的 paginationArea 配置
|
||||
export const createCardProPagination = ({
|
||||
currentPage,
|
||||
@@ -578,11 +577,10 @@ export const createCardProPagination = ({
|
||||
total,
|
||||
onPageChange,
|
||||
onPageSizeChange,
|
||||
isMobile = false,
|
||||
pageSizeOpts = [10, 20, 50, 100],
|
||||
showSizeChanger = true,
|
||||
}) => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
if (!total || total <= 0) return null;
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user