SVGR React Native .svg 文件

SVGR React Native .svg file

我有一个令人困惑的 .svg 文件,其中矢量是用笔触和填充创建的。我想自定义本地 .svg 文件的颜色。例如,如果我写

<TestIconFlexible width='100%' height='100%' fill='red' />

我的 React Native 会将真实的矢量颜色更改为红色。

我的测试 .svg 文件是这个

<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M19 12.5H23" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M9 12.5H13" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M11 10.5V14.5" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M21.5022 5.96747L10.5004 5.99999C8.9722 6.00011 7.49286 6.53852 6.32207 7.52073C5.15129 8.50293 4.3639 9.86615 4.09811 11.3711L4.09918 11.3713L2.05363 21.8916C1.92442 22.6247 2.03227 23.3798 2.36151 24.0474C2.69074 24.715 3.22422 25.2602 3.88446 25.6039C4.5447 25.9476 5.29732 26.0719 6.03301 25.9587C6.7687 25.8455 7.44915 25.5008 7.97553 24.9745L7.97533 24.9743L13.3798 19L21.5022 18.9675C23.2261 18.9675 24.8794 18.2826 26.0984 17.0637C27.3173 15.8447 28.0022 14.1914 28.0022 12.4675C28.0022 10.7436 27.3173 9.09026 26.0984 7.87127C24.8794 6.65229 23.2261 5.96747 21.5022 5.96747V5.96747Z" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M27.9035 11.3387L29.9474 21.8916C30.0766 22.6247 29.9688 23.3798 29.6395 24.0474C29.3103 24.715 28.7768 25.2602 28.1166 25.6039C27.4563 25.9476 26.7037 26.0719 25.968 25.9587C25.2323 25.8455 24.5519 25.5008 24.0255 24.9745L24.0257 24.9743L18.625 18.979" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

我已经为 React Native 项目设置了所有必要的配置,以呈现我的本地 .svg 文件。这是我的 .svgrrc 文件配置。

{
  "replaceAttrValues": {
    "#000": "{props.fill}"
  }
}

我认为如果我从我的 TestIconFlexible“组件”传递填充 属性,并且有 #000 种颜色,它会变成我传递的颜色。换句话说,#000 是我可以从 props 更改的关键字。

当我 运行 项目时,我得到完全红色的 svg 图标。

这些是我对 React Native App 的所有依赖。

"dependencies": {
    "@expo/metro-config": "^0.1.64",
    "@react-native-community/masked-view": "0.1.10",
    "@react-navigation/bottom-tabs": "^5.11.10",
    "@react-navigation/native": "^5.9.4",
    "@react-navigation/stack": "^5.14.4",
    "expo": "~41.0.1",
    "expo-app-loading": "^1.0.3",
    "expo-font": "~9.1.0",
    "expo-status-bar": "~1.0.4",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
    "react-native-collapsible": "^1.5.3",
    "react-native-gesture-handler": "~1.10.2",
    "react-native-iphone-x-helper": "^1.3.1",
    "react-native-raw-bottom-sheet": "^2.2.0",
    "react-native-reanimated": "~2.1.0",
    "react-native-safe-area-context": "3.2.0",
    "react-native-screens": "~3.0.0",
    "react-native-svg": "12.1.0",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@react-native-community/eslint-config": "^2.0.0",
    "eslint": "^7.25.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-config-react-app": "^6.0.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "react-native-svg-transformer": "^0.14.3"
  },

根据我的经验,使用 svgs 非常棘手。所以我所做的通常是使用 react-native-svg in combination with online SVGR tool.

将它们转换为反应组件

只需将您的 svg 复制粘贴到 SVGR playground 输入,选中 'react-native' 勾选 expand props to 'none' 并将结果作为 React 组件复制粘贴到您的代码中,然后添加道具和函数等。但是删除 xmlns="http://www.w3.org/2000/svg" 行,由于某种原因,这每次都会给我错误。

这里有一个 svg 组件在我的一个项目中的外观示例:

import { colors } from '@src/style/colors';
import React from 'react';
import Svg, { Path } from 'react-native-svg';

interface Props {
  fill?: string;
}
const Check = ({ fill = colors.greenAccent }: Props) => {
  return (
    <Svg width="18" height="18" viewBox="0 0 18 18" fill="none">
      <Path
        d="M8.99995 0C4.03741 ..." // i deleted the long path here for simplicity fo example
        fill={fill}
      />
    </Svg>
  );
};

export default Check;

然后像这样在我的 JSX 中使用它:

import { Check } from '@src/assets/icons';

... //other code

<View style={styles.textWrap}>
  <Check />
    <Paragraph style={styles.text}>{text}</Paragraph>
</View>

... //other code