You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Material UI分页组件RTL模式箭头显示异常求助

解决Material UI Pagination组件RTL布局箭头方向错误问题

我正尝试为React Material UI的Pagination组件设置RTL(从右到左)布局,但分页箭头未正确适配RTL方向。尝试过相关解决方案但未生效,希望得到帮助。

组件实现代码

import React, { useState, useEffect, useMemo, useRef } from "react";
import TransactionsWithout220Service from "../services/TransactionsWithout220Service";
import Pagination from "@material-ui/lab/Pagination";
import { useTable } from "react-table";
import Spinner from "./Spinner";

import { createTheme, ThemeProvider } from "@mui/material/styles";
import rtlPlugin from "stylis-plugin-rtl";
import { prefixer } from "stylis";
import { CacheProvider } from "@emotion/react";
import createCache from "@emotion/cache";


const themeRtl = createTheme({
  direction: "rtl"
});
const themeLtr = createTheme({
  direction: "ltr"
});
// Create rtl cache
const cacheRtl = createCache({
  key: "muirtl",
  stylisPlugins: [prefixer, rtlPlugin]
});



const TransactionsWithout220List = (props) => {

  const [transactions, setTransactions] = useState([]);
  const transactionsRef = useRef();
  const [page, setPage] = useState(1);
  const [count, setCount] = useState(0);
  const [pageSize, setPageSize] = useState(3);
  const pageSizes = [20];

  const [loading, setLoading] = useState(false);

  transactionsRef.current = transactions;

  const [direction, setDirection] = useState("rtl");

  
  const getRequestParams = (page, pageSize) => {
    let params = {};
    if (page) {
      params["page"] = page ;
    }
    if (pageSize) {
      params["size"] = pageSize;
    }
    return params;
  };


  const retrieveTransactions = () => {
    setLoading(true);
    const params = getRequestParams(page, pageSize);
    TransactionsWithout220Service.getAll(params)
      .then((response) => {
        const { Data, TotalPages } = response.data;
        setTransactions(Data);
        setCount(TotalPages);
        setLoading(false);
        console.log(response.data);
      })
      .catch((e) => {
        console.log(e);
      });
  };

  useEffect(retrieveTransactions, [page, pageSize]);

  const handlePageChange = (event, value) => {
    setPage(value);
  };
  const handlePageSizeChange = (event) => {
    setPageSize(event.target.value);
    setPage(1);
  };


  const refreshList = () => {
    retrieveTransactions();
  };


  const columns = useMemo(
    () => [

      {
        Header: "آدرس",
        accessor: "Address",
      },
      {
        Header: "تلفن همراه",
        accessor: "CellPhoneNumber",
      },
      {
        Header: "نام",
        accessor: "FirstName",
      },
      {
        Header: "نام خانوادگی",
        accessor: "LastName",
      },
      
    ],
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable({
    columns,
    data: transactions,
  });


  if (loading) {
    return (
      <Spinner message={`لصفا صبر کنید`} />
    );
  }

  return (
    <div className="list row mt-5 pt-5 mb-5 pb-5" align="right" >
      <div className="col-md-12 list">
        <div className="mt-3" dir="rtl">
          {"تعداد در هر صفحه: "}
          <select onChange={handlePageSizeChange} value={pageSize} >
            {pageSizes.map((size) => (
              <option key={size} value={size} >
                {size}
              </option>
            ))}
          </select>

          <CacheProvider value={cacheRtl}>
          <ThemeProvider theme={direction === "rtl" ? themeRtl : themeLtr}>
            <Pagination
                  className="my-3"
                  count={count}
                  page={page}
                  siblingCount={1}
                  boundaryCount={1}
                  variant="outlined"
                  shape="rounded"
                  color="primary"
                  onChange={handlePageChange}
                />
          </ThemeProvider>
          </CacheProvider>
          
        </div>
        <table
          className="table table-striped table-bordered"
          {...getTableProps()}
        >
          <thead>
            {headerGroups.map((headerGroup) => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map((column) => (
                  <th {...column.getHeaderProps()}>
                    {column.render("Header")}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody {...getTableBodyProps()}>
            {rows.map((row, i) => {
              prepareRow(row);
              return (
                <tr {...row.getRowProps()}>
                  {row.cells.map((cell) => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
};

export default TransactionsWithout220List;

当前分页显示效果

分页显示效果

我希望箭头能够适配RTL(从右到左)的布局方向。


解决方案

1. 提升CacheProvider与ThemeProvider的层级

当前你只在Pagination外层包裹了缓存和主题组件,这会导致Material UI的RTL样式无法全局生效。建议将CacheProvider和ThemeProvider移到组件最外层,包裹整个返回内容:

return (
  <CacheProvider value={cacheRtl}>
    <ThemeProvider theme={direction === "rtl" ? themeRtl : themeLtr}>
      <div className="list row mt-5 pt-5 mb-5 pb-5" align="right" >
        {/* 原有内容 */}
      </div>
    </ThemeProvider>
  </CacheProvider>
);

2. 手动替换RTL模式下的箭头图标

如果主题配置仍不生效,可以直接根据方向状态自定义箭头:
首先导入所需图标组件:

import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';

然后修改Pagination组件的图标属性:

<Pagination
  className="my-3"
  count={count}
  page={page}
  siblingCount={1}
  boundaryCount={1}
  variant="outlined"
  shape="rounded"
  color="primary"
  onChange={handlePageChange}
  // 适配RTL的箭头
  nextIcon={direction === 'rtl' ? <ArrowBackIcon /> : <ArrowForwardIcon />}
  prevIcon={direction === 'rtl' ? <ArrowForwardIcon /> : <ArrowBackIcon />}
/>

3. 移除直接操作document.body的代码

删除document.body.dir = direction;这行代码,避免和Material UI的主题方向配置冲突,改用最外层容器的dir属性或者主题配置来控制方向。

内容的提问来源于stack exchange,提问作者mohsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:58:35