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

Chakra UI表格表头样式在tsx与jsx后缀文件中显示不一致问题

问题现象

我在app.tsx中编写了如下简单函数用于渲染表格,此时表头显示正常(黑底白字),可读性良好。
表头显示正常效果图

import React from 'react';
import { Table, Thead, Tbody, Tr, Th, Td } from "@chakra-ui/react"

export default function App() {
  return(
    <Table variant="simple" size="sm">
      <Thead>
        <Tr>
          <Th>A</Th>
          <Th>B</Th>
        </Tr>
      </Thead>
      <Tbody>
        <Tr>
          <Td>a</Td>
          <Td>b</Td>
        </Tr>
      </Tbody>
    </Table>
  )
}

但如果我将文件重命名为app.jsx,同一表格渲染后表头显示模糊、难以辨认,效果如下:
表头显示异常效果图

复现步骤

git clone https://github.com/somguyth/chakra-ui-header-bug.git
cd chakra-ui-header-bug
npm install
npm run dev

启动后访问localhost:9000,将app.jsx重命名为app.tsx,观察代码重编译后表头颜色发生变化。
显示正常时(app.tsx)的表头元素属性:
正常表头元素属性截图
显示异常时(app.jsx)的表头元素属性:
异常表头元素属性截图

补充说明

我尝试临时修复该问题,在index.tsx之外,额外在app.jsx中也添加<ChakraProvider theme={darkTheme}>包裹,此时表头恢复正常,检查元素发现th标签的class从错误的css-r10se1变回了正确的css-4v3u8n。我不清楚该问题的根因,也希望获得不需要重复声明ChakraProvider的正确修复方案。

相关配置代码

index.tsx

import React from "react";
import ReactDOM from "react-dom";
import { ChakraProvider, extendTheme } from "@chakra-ui/react"


import App from "./app"

const darkTheme = extendTheme({
  config: {
    useSystemColorMode: false,
    initialColorMode: "dark"
  }
});


ReactDOM.render(
    <ChakraProvider theme={darkTheme}>
        <App />
    </ChakraProvider>,
    document.getElementById("root")
);

webpack.config.js module规则配置

module: {
  rules: [
    {
      test: /\.tsx?$/,
      use: "ts-loader",
      exclude: /node_modules/
    },
    {
      test: /\.m?jsx?$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env', "@babel/preset-react"]
        }
      },
      resolve: {
        fullySpecified: false,
      },
    },
    {
      test: /\.css$/,
      use: ['style-loader', 'css-loader']
    }
  ],
},

.babel.rc配置

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

package.json配置

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve"  
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@chakra-ui/icons": "^1.0.14",
    "@chakra-ui/react": "^1.6.5",
    "@emotion/react": "^11.4.0",
    "@emotion/styled": "^11.3.0",
    "css-loader": "^5.2.7",
    "framer-motion": "^4.1.17",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-table": "^7.7.0",
    "typescript": "^4.3.5"
  },
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/preset-env": "^7.14.7",
    "@babel/preset-react": "^7.14.5",
    "@types/react-dom": "^17.0.9",
    "@types/react-table": "^7.7.2",
    "babel-loader": "^8.2.2",
    "html-webpack-plugin": "^5.3.2",
    "ts-loader": "^9.2.3",
    "webpack": "^5.45.1",
    "webpack-cli": "^4.7.2",
    "webpack-dev-server": "^3.11.2"
  }
}

根因与解决方案

根因

该问题是Chakra UI v1版本混合TS/JS编译场景下的样式注入冲突导致的:
你的webpack配置中,TS/TSX文件走ts-loader编译,JS/JSX走babel-loader编译,两种编译链路对Chakra UI依赖的emotion样式库的class生成规则不一致,导致JSX文件中渲染的Chakra组件没有正确继承全局ChakraProvider注入的暗色主题配置,使用了默认的亮色主题样式,才会出现浅色表头在暗色背景下模糊的问题。

解决方案

不需要重复声明ChakraProvider,按以下任意一种方式调整即可:

  • 统一编译链路:将JSX文件也纳入ts-loader的编译范围,修改webpack.config.js中的ts-loader匹配规则为test: /\.[jt]sx?$/,移除单独的JSX babel-loader规则,同时在tsconfig.json中设置"allowJs": true即可。
  • 给babel-loader添加emotion预设:安装@emotion/babel-preset-css-prop,修改.babelrc的presets配置,新增emotion的预设,确保babel编译JSX时和ts-loader的样式生成规则对齐:
{
  "presets": ["@babel/preset-env", "@babel/preset-react", "@emotion/babel-preset-css-prop"]
}
  • 显式指定组件样式:如果不想修改编译配置,可以直接给Th组件显式指定样式,例如<Th color="white" bg="gray.800">即可强制覆盖默认样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 17:24:03