简体   繁体   English

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

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

I have the following component:我有以下组件:

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 
}

As you can see, the component accepts an icon of JSX.Element (not sure how can I strict it to SVG only).如您所见,该组件接受一个 JSX.Element 图标(不知道如何将其限制为仅 SVG)。

After that, it should look in the icon tree for children who has fill and stroke attribute and replace accordingly.之后,它应该在icon树中查找具有fillstroke属性的子项并相应地替换。 Meaning, if there's a path with fill , it will replace it with the given fill.意思是,如果有一个带有fill的路径,它将用给定的 fill 替换它。 If a path doesn't have a fill , then it won't be added.如果路径没有fill ,则不会添加它。

How can I achieve this behavior?我怎样才能实现这种行为?

I think I have managed to get what you want working:我想我已经设法得到你想要的工作:

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>
    );
}

In AppIcon.css :AppIcon.css

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

Using the component:使用组件:

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

Explanation:解释:

  • Firstly the icon property on the Props interface should be children .首先,道具界面上的icon属性应该是children React will populate that property with any children of the Component. React 将使用组件的任何子项填充该属性。 As far as I understand there is no way to limit that to a certain tag name unfortunately.据我所知,不幸的是,没有办法将其限制为某个标签名称。

  • It then renders the child under a div tag.然后它在 div 标签下呈现孩子。 Here I give that div tag a className for identification later and I give the div a style with two css custom properties where their values match the fill and stroke provided by the props.在这里,我给那个div标签一个 className 以便稍后识别,我给这个 div 一个带有两个css 自定义属性的样式,其中它们的值与道具提供的填充和描边相匹配。 (TypeScript does not like this as they are not defined so thus we have // @ts-ignore ) (TypeScript 不喜欢这样,因为它们没有定义,所以我们有// @ts-ignore

  • Those properties can be accessed by any descendants / children of the div element.这些属性可以被 div 元素的任何后代/子元素访问。 So in the adjoining stylesheet we set elements in the svg to use the variables set with the var() keyword in the stylesheet.因此,在相邻的样式表中,我们将 svg 中的元素设置为使用样式表中通过var()关键字设置的变量。

demo in codesandbox 代码沙盒中的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM