如何将 svg 作为道具传递给可按下的组件

how to pass svg as a prop to a pressable component

我在这两个库的帮助下使用了很多 svg 图像

"react-native-svg": "^12.1.0",
"react-native-svg-transformer": "^0.14.3",

然后我就可以像下面这样导入和使用 svg 图像了。

import Logo from '../assets/svg/img.svg';
...
...
<Logo height={60} />
...

下面是我的自定义按钮

***imaginary part // import Logo from '../assets/svg/img.svg';

const ButtonPressable = (props) => {
  return (
    <View>
      <Pressable
        style={[
          props.backgroundColor
            ? {backgroundColor: props.backgroundColor}
            : {backgroundColor: '#0077b6'},
        ]}>
        <Text>
          {props.text ? props.text : ''}
        </Text>

***imaginary part // <Logo height={60} />

      </Pressable>
    </View>
  );
};

我正在使用上面的组件,如下所示

<ButtonPressable text="Login" backgroundColor="red" />

如果你看一下上面代码中的虚部。通过这种方式,我可以在组件内显示 svg 图像。 但是,我需要像下面这样将 svg 图像显示为道具。

<ButtonPressable text="Login" backgroundColor="red" svg="../assets/svg/img.svg" />

如何将 svg 路径作为 prop 传递并在组件内显示?

你这样做怎么样?

<img src={require(props.svg)} alt="Logo" height={60} />

将您的 SVG 转换为 JSX。然后您可以将其用作图标组件。

你可以使用这个SVG 2 JSX or SVGR Playground

例如下面是一个左箭头 svg。

<svg xmlns="http://www.w3.org/2000/svg" width="20" height="16.327" viewBox="0 0 20 16.327"><path d="M-9.974-7.735a.988.988,0,0,0,.334.722L-2.489.127a.982.982,0,0,0,.7.3A.918.918,0,0,0-.841-.5a.943.943,0,0,0-.269-.679L-3.523-3.631l-3.63-3.306,2.606.162H9.078a.913.913,0,0,0,.948-.959.913.913,0,0,0-.948-.959H-4.546l-2.6.162,3.619-3.306,2.412-2.456a.961.961,0,0,0,.269-.679.918.918,0,0,0-.948-.926.964.964,0,0,0-.722.323L-9.64-8.456A.988.988,0,0,0-9.974-7.735Z" transform="translate(9.974 15.898)"/></svg>

然后你可以使用上面的 link 并将其转换为 JSX。

import * as React from 'react';
import Svg, { Path } from 'react-native-svg';

export interface IconLeftArrowProps {
  width?: number;
  height?: number;
  color?: string;
}

/**
 * IconLeftArrow
 * Base svg file
 * assets/images/svgsSrc/icon_arrow_left.svg
 * @param
 * width   {Number} [ svg width size,  default size 20 ]
 * height  {Number} [ svg height size, default size 16.327 ]
 * color   {String} [ svg fill color,  default color BLACK(#000000) ]
 */
const IconLeftArrow: React.FC<IconLeftArrowProps> = ({
  width = 20 ,
  height = 16.327 ,
  color = #000000,
}) => (
  <Svg width={width} height={height} viewBox="0 0 20 16.327">
    <Path
      fill={color}
      d="M-9.974-7.735a.988.988,0,0,0,.334.722L-2.489.127a.982.982,0,0,0,.7.3A.918.918,0,0,0-.841-.5a.943.943,0,0,0-.269-.679L-3.523-3.631l-3.63-3.306,2.606.162H9.078a.913.913,0,0,0,.948-.959.913.913,0,0,0-.948-.959H-4.546l-2.6.162,3.619-3.306,2.412-2.456a.961.961,0,0,0,.269-.679.918.918,0,0,0-.948-.926.964.964,0,0,0-.722.323L-9.64-8.456A.988.988,0,0,0-9.974-7.735Z"
      transform="translate(9.974 15.898)"
    />
  </Svg>
);

export default IconLeftArrow;

我不能肯定地说转换器工作完美,因为我也遇到过问题。但如果它不起作用,请尝试将 svg 更改为 Svg,将路径更改为 Path 等等。

然后您可以直接导入并使用它们。

下面是一个例子,说明如何传递从主组件导入的SVG。这个想法是 ButtonPressable 将有一个道具,svg,它可以是任何东西,但也可以是 SVG。请修改ButtonPressable如下

const ButtonPressable = (props) => {
  return (
    <View>
      <Pressable
        style={[
          props.backgroundColor
            ? {backgroundColor: props.backgroundColor}
            : {backgroundColor: '#0077b6'},
        ]}>
        <Text>
          {props.text ? props.text : ''}
        </Text>

{props.svg? <props.svg height={60} /> : null}

      </Pressable>
    </View>
  );
};

然后像这样将它们导入任何地方并传递 SVG

import Logo from '../assets/svg/img.svg';
<ButtonPressable text="Login" backgroundColor="red" svg={Logo} />

这将使 ButtonPressable 保持可重复使用。

您可以通过多种方式在项目中使用 SVG,

  1. 正在将 SVG 转换为字体文件并将它们导入到您的项目中。我还没有尝试过这个,因为每次您必须添加一个图标时都必须执行此过程。

  2. 使用react-native-svg-transformer,我自己用过这个,很容易实现(虽然没有在世博会上试过)。文档清楚说明如何在项目中实现。

而且你可以创建2个文件,

  1. 导出所有 svg
import LeftArrowIcon from "@src/assets/svg/leftArrow.svg";

export const IconFiles = {
  LeftArrowIcon
};

export const IconNames = {
   LEFT_ARROW_ICON: "LeftArrowIcon", // value should as same as icon fileimport
};

  1. Icons 的单个通用组件(基于 svgs)
// icon.tsx
import { IconFiles } from "@src/themes/icons";

// props: {iconName: string} example: LEFT_ARROW_ICON
export default (props) => {
  const I = IconFiles[`${props.iconName}`];
  return (
    <I width={defaultWidth || fromProps} height={defaultHeight || fromProps} />
  );
};

最终在你的 ButtonComponent,

const ButtonPressable = (props) => {
  return (
    <View>
      <Pressable
        style={[
          props.backgroundColor
            ? {backgroundColor: props.backgroundColor}
            : {backgroundColor: '#0077b6'},
        ]}>
        <Text>
          {props.text ? props.text : ''}
        </Text>
       <Icon iconName={props.iconName} />
      </Pressable>
    </View>
  );
};

在你的父组件中,你可以像这样使用它,

<ButtonPressable 
  text="Login" 
  backgroundColor="red" 
  iconName={IconNames.LEFT_ARROW_ICON} 
/>