重复问题
- 我搜索了现有的问题
最新版本
- 我测试了最新版本
重现步骤 🕹
链接到实时示例:
https://codesandbox.io/s/zealous-benz-3zmg7x?file=/src/App.tsx
步骤:
- 在任何地方使用一个
FormControl
组件 - 使它呈现为一个
Fragment
- 在控制台中看到错误。
当前行为 😯
它在控制台中产生错误:
Warning: Invalid prop `className` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.
预期行为 🤔
没有错误。
上下文 🔦
我这样做是因为我需要 FormControl 不在表单元素周围产生额外的元素,这是由于 CSS Grid 的原因。
应用 display: contents
对于 CSS Grid 工作来说是不够的,而 subgrid
不幸的是仍然没有得到广泛的支持。
你的环境 🌎
npx @mui/envinfo
System:
OS: Windows 10 10.0.19045
Binaries:
Node: 18.15.0 - C:\Program Files\nodejs\node.EXE
Yarn: Not Found
npm: 9.8.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 115.0.5790.102
Edge: Spartan (44.19041.1266.0), Chromium (114.0.1823.86)
npmPackages:
@emotion/react: 11.10.6
@emotion/styled: 11.10.6
@mui/base: 5.0.0-alpha.124
@mui/core-downloads-tracker: 5.11.16
@mui/material: 5.11.16
@mui/private-theming: 5.12.0
@mui/styled-engine: 5.11.16
@mui/styles: 5.12.0
@mui/system: 5.11.16
@mui/types: 7.2.4
@mui/utils: 5.12.0
@types/react: 18.2.0
react: 18.2.0
react-dom: 18.2.0
typescript: 4.9.5
我正在使用 Firefox 115,以防万一它有影响。
5条答案
按热度按时间jum4pzuy1#
一个可能的(但愚蠢的)解决方法:
基本上,在
Noop
的位置代替Fragment
,其中 Noop 吃掉了错误,Fragment 通常会发出警告,提醒传递了 props。这并不是非常优雅的方法,但是至少它清理了控制台。mnemlml82#
@thany 我非常确定这不能正常工作,因为
FormControl
需要接收props以实现其预期功能,但Fragment
只能接收key
和children
,正如错误信息所解释的那样。我这样做是因为我需要FormControl不在其表单元素周围产生额外的元素,这是由于CSS Grid的原因。
你能分享一下你的用例或者你试图实现的布局吗?
tez616oj3#
每个FormControl包含一个标签和一个输入控件。我(我们和我们的设计师)讨厌abel-inside-or-above-the-control布局,我们必须提供一个经典但经过验证的布局,左边是标签,右边是字段。
如果每个FormControl都生成一个
<div>
,这是不可能实现的,因为CSS Grid需要所有单元格都是它的子元素才能工作。目前,对于表单来说,有多个FormControl组件会产生大致如下的伪代码:
Obne不能将CSS Grid应用于此并期望标签和输入自动成为网格单元格。CSS Grid就是这么工作的。要使它正确地呈现为网格,唯一的正确方法是消除这些div:
这样一来,标签和输入就成为了表单的子元素,即CSS Grid。
现在,说实话,我不认为FormControl绝对需要将自己渲染为div。为什么?我认为FormControl只是一个空组件,为其包含的表单元素组件提供一些功能。它不需要自己渲染任何东西。它当前确实(或者尝试无论如何😒)这样做,但是为了什么目的?我不需要它的类名存在于HTML结构中,我也肯定不喜欢被限制在每个标签+输入组合都被包裹在另一个元素中 - 我需要并希望不要求这一点。
更一般地说 - UI框架不应该规定应该在其组件外部渲染哪些HTML元素。它永远不应该渲染只有它需要而浏览器不需要的任何HTML元素。任何仅用于功能性的 Package 组件都不应该渲染任何HTML,而只应该为其子组件提供预期的功能。这有很多“应该”,所以请随意提出异议,只要我们能解决上面描述的问题就好啦😉
现在,如果有除了FormControl之外的其他组件,我可以用来替代它,同时仍然为其子输入组件提供状态等,我洗耳恭听关于它的建议。
编辑:
@thany我相当确定这不能像
FormControl
那样工作,因为FormControl
需要接收其预期功能的属性,但Fragment
无法接收除key
和children
之外的任何内容,正如错误消息所解释的那样。顺便说一下,如果我字面意义上理解 - FormControl仍然可以接收世界上所有的属性而不渲染任何内容。接收属性与组件返回的内容无关。我相信你明白这一点,但我只是想确保我们都在同一页上。
问题在于FormControl能够告诉它应该渲染哪个组件,盲目地假设它传递给该组件的所有内容,它也可以在自己的回合接收到,这显然是一个不安全的假设。
cpjpxq1n4#
@mj12albert,我认为我们应该允许这样做。FormControl不会设置或依赖事件处理程序。我们可以允许
React.Fragment
或null
作为component
/slots.root
,或者添加一个新的属性来控制FormControlRoot
是否被渲染。vktxenjb5#
@mj12albert,我认为我们应该允许这个。FormControl不会设置或依赖事件处理程序。我们可以允许
React.Fragment
或null
作为component
/slots.root
,或者添加一个新的prop来控制FormControlRoot
是否被渲染。我更倾向于后者,因为完全有可能构建一个组件,它也不能接受
className
prop或其他FormControl试图传递的属性。添加一些严格的propType验证,它也可能像Fragment中的错误一样输出一个错误。