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
相关产品推荐
相关产品推荐

