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

使用Grommet、React与styled-components时遇报错求助

Grommet组件引入后报错警告排查方案

问题背景

在React项目中引入任意Grommet组件时,持续出现大量报错与警告,尝试通过StyleSheetManager修复但仍有新错误。

依赖版本

"dependencies": {
  "grommet": "^2.34.2",
  "grommet-icons": "^4.12.0",
  "react": "^18.2.0",
  "react-dom": "^18.2.0",
  "react-router-dom": "^6.21.3",
  "styled-components": "^6.1.8"
}

相关代码

import { NavLink } from 'react-router-dom'
import styled from 'styled-components';

import { Button, Box } from 'grommet'

const Menu = () => {
  return (
  
      <Box>
        <NavLink to="recipes">RECIPES
        </NavLink>
        <NavLink to="addrecipe">ADD RECIPE</NavLink>
        <NavLink to="generator">RECIPE GENERATOR</NavLink>
      </Box>

  )
}

export default Menu

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" />
    <title>Vite + React</title>
    <style type="text/css">
      body { margin: 0 }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

main.jsx

import { Grommet } from 'grommet';
import ReactDOM from 'react-dom/client'
import App from './App'
// import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
// import { NotificationContextProvider } from './context/NotificationContext'
// import { UserContextProvider } from './context/UserContext'
import { BrowserRouter } from 'react-router-dom'

const customTheme = {
  global: {
    colors: {
      'light-2': '#f5f5f5',
      'text': { light: 'rgba(0, 0, 0, 0.87)', },
    },
    font: {
      family: 'Roboto',
      size: '14px',
      height: '20px',
    },
  },
};

ReactDOM.createRoot(document.getElementById('root')).render(
    <Grommet theme={customTheme} >
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Grommet>
)

报错与警告信息

  1. StyledComponent.ts:162 styled-components: 检测到未知属性"responsive"被传递到DOM,这可能会触发React控制台错误。若要自动过滤未知属性,可通过<StyleSheetManager shouldForwardProp={...}>(结合@emotion/is-prop-valid这类工具)开启该功能,或考虑使用临时属性(添加$前缀自动过滤)。
  2. Warning: React无法识别DOM元素上的directionProp属性。若你有意让它作为自定义属性出现在DOM中,请改为小写directionprop;若不小心从父组件传递了该属性,请从DOM元素中移除。
  3. react-dom.development.js:86 Warning: 为非布尔属性responsive传递了true值。如果要写入DOM,请传递字符串形式:responsive="true"或responsive={value.toString()}。

解决方案

核心问题原因

Grommet v2.x与styled-components v6.x存在兼容性问题——styled-components v6改变了属性转发的默认行为,而Grommet内部的一些组件属性没有按照新规则处理,导致非DOM属性被错误传递到DOM节点。

步骤1:安装属性校验工具

先安装@emotion/is-prop-valid,用来识别哪些属性是合法的DOM属性:

npm install @emotion/is-prop-valid

步骤2:全局配置StyleSheetManager

在main.jsx中引入StyleSheetManager和isPropValid,并包裹整个Grommet应用,配置shouldForwardProp来过滤非法属性:

import { Grommet } from 'grommet';
import ReactDOM from 'react-dom/client'
import App from './App'
import { BrowserRouter } from 'react-router-dom'
import { StyleSheetManager } from 'styled-components';
import isPropValid from '@emotion/is-prop-valid';

const customTheme = {
  global: {
    colors: {
      'light-2': '#f5f5f5',
      'text': { light: 'rgba(0, 0, 0, 0.87)', },
    },
    font: {
      family: 'Roboto',
      size: '14px',
      height: '20px',
    },
  },
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <StyleSheetManager shouldForwardProp={isPropValid}>
    <Grommet theme={customTheme} >
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Grommet>
  </StyleSheetManager>
)

步骤3:验证修复效果

重启项目后,检查控制台是否还有之前的报错警告。如果仍有个别属性问题,可以针对特定组件使用临时属性(在Grommet组件属性前加$),但全局配置应该能解决大部分问题。

备选方案:降级styled-components

如果全局配置后仍有问题,可以尝试将styled-components降级到v5.x版本,因为Grommet v2.x对v5的兼容性更好:

npm install styled-components@^5.3.11

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:35:14