如何修改给定的 JSX.Element 属性 的 children?

How to modify children of a given JSX.Element property?

我有以下组件:

import React, { ReactElement } from 'react'

interface Props {
  icon: JSX.Element; // should accept only svg
  fill?: string;
  stroke?: string;
}

export default function AppIcon(props: Props): ReactElement {
  // TODO:
  // Replace: svg *[fill] = props.fill
  // Replace: svg *[stroke] = props.stroke 
}

如您所见,该组件接受 JSX.Element 图标(不确定如何将其限制为仅 SVG)。

之后,它应该在 icon 树中查找具有 fillstroke 属性的 children 并进行相应替换。意思是,如果有 fill 的路径,它将用给定的填充替换它。如果路径没有 fill,则不会添加。

我怎样才能实现这种行为?

我想我已经成功实现了你想要的效果:

import React, { ReactElement } from "react";
import "./AppIcon.css";

interface Props {
    children: JSX.Element;
    fill?: string;
    stroke?: string;
}

export default function AppIcon(props: Props): ReactElement {
    return (
        // @ts-ignore
        <div className="AppIcon" style={{ "--fill": props.fill, "--stroke": props.stroke }}>
            {props.children}
        </div>
    );
}

AppIcon.css中:

.AppIcon > svg * {
    fill: var(--fill);
    stroke: var(--stroke);
}

使用组件:

...
<AppIcon fill="blue" stroke="yellow">
    <svg>
        <circle cx="50" cy="50" r="40" strokeWidth="3" />
    </svg>
</AppIcon>
...

解释:

  • 首先Props界面上的icon属性应该是children。 React 将使用组件的任何 children 填充 属性。据我所知,不幸的是,没有办法将其限制为某个标签名称。

  • 然后在 div 标签下呈现 child。在这里,我给 div 标签一个 className 以便稍后识别,我给 div 一个带有两个 css custom properties 的样式,其中它们的值与道具提供的填充和描边相匹配。 (TypeScript 不喜欢这样,因为它们没有定义,所以我们有 // @ts-ignore

  • 这些属性可以被 div 元素的任何后代 / children 访问。因此,在相邻的样式表中,我们将 svg 中的元素设置为使用样式表中通过 var() 关键字设置的变量。

demo in codesandbox