如何通过道具动态更改SVG孩子的颜色?

时间:2019-11-11 14:20:05

标签: reactjs svg

我正在使用ReactComponent导入SVG。这是相关的代码:

import { ReactComponent as SuccessSVG } from "success.svg";

function SuccessIcon() {
  return <SuccessSVG />;
}

这是SVG本身:

<svg viewBox="0 0 233.3 233.3">
  <circle class="circle" cx="116.65" cy="116.65" r="116.65" />
  <path
    class="ok"
    d="M97.28,167.38l-33.7-33.7a6.34,6.34,0,1,1,9-9l29.21,29.21,76-76a6.34,6.34,0,1,1,9,9l-80.48,80.48A6.34,6.34,0,0,1,97.28,167.38Z"
    transform="translate(-8.51 -6.01)"
  />
</svg>

我想通过道具动态更改circlepath的颜色。显然是这样的:

function SuccessIcon({ circleColor, pathColor) {
  ...
  ...
}

我已经看过this question。我不想使用接受的答案的解决方案。另一个答案更接近我的愿望,但我无法实现。

顺便说一句,我不想​​在组件中直接使用SVG。

2 个答案:

答案 0 :(得分:2)

您已经将SuccessSVG提取到其自己的组件中。现在,您只需要通过props传递要动态的配置

const SuccessSvg = ({ cx, cy }) => {
    return (
        <svg viewBox="0 0 233.3 233.3" >
            <circle class="circle" cx={cx} cy={cy} r="116.65" />
            <path
                class="ok"
                d="M97.28,167.38l-33.7-33.7a6.34,6.34,0,1,1,9-9l29.21,29.21,76-76a6.34,6.34,0,1,1,9,9l-80.48,80.48A6.34,6.34,0,0,1,97.28,167.38Z"
                transform="translate(-8.51 -6.01)"
            />
        </svg>
    )
}

const Component = () =>{
    return(
        <SuccessSvg color='blue' />
    )
}

遗憾的是,您必须考虑这一折衷。通过将svg声明为独立组件,您可以编写更多代码并可以控制自定义。这样您就可以传递将在jsx结构中深入应用的道具

const CustomSVG = ({ svgProps, circleProps }) =>{
    return(
        <svg {...svgProps}>
            <circle {...circleProps} />
        </svg>
    )
}

这就是链接问题的OP将svg包装到组件中的原因,以便他可以将自定义className注入svg中。声明性组件很棒,但是您受到它们的API的限制。在您的情况下,我看不到太多选择,要么将结构抽象为自己的组件,要么使用嵌套的选择器。

答案 1 :(得分:1)

如果您不想按照@Dupocas的建议使用组件,唯一的方法是设置SVG的样式:

// Example of CSS-in-JS , can be achieved with simple className.
const SVGContainer = styled.div`
  svg {
    path {
      fill: ${({ circleColor }) => circleColor};
    }
  }
`;

function SuccessIcon({ circleColor }) {
  return (
    <SVGContainer circleColor={circleColor}>
      <SuccessSVG />
    </SVGContainer>
  );
}

const App = () => {
  return <SuccessIcon circleColor="palevioletred" />;
};

Edit react-antd-styled-template