How to display SVG files and change colors dynamically in React Native.
Tags: reactnative, node, javascript, svg
Published: 2022-01-13 03:30:50

Hi guys,

In Japan, I have often heard that React Native(RN) is "dead" or "not good" or " Flutter is best" since about three years ago. 
Still, it's a solid fact that FaceBook, Instagram ranks high among the apps used in the world. I often tired when I search for "I try to do something on RN", all I get is old information or information that is not buildable.

Please note that the content of this article is also my method.

## Why do need to change colors dynamically?

Because I should support Dark Mode!
Sadly? I think the proportion of UI / UX in application development is increasing year by year. No matter how much Jetpack Compose (Android) and SwiftUI (iOS) evolve, the burden on us developers will not decrease.(Especially, I think that animations in screen transitions are demons.)

Complaints Aside, let's display the SVG files.

## Use react-native-svg-transformer.

I've seen some articles about using "[react-native-svg-uri](https://github.com/vault-development/react-native-svg-uri)", but I continue to use "[react-native-svg-transformer](https://github.com/kristerkari/react-native-svg-transformer)".(I don't think I've experienced react-native-svg-uri working properly.)

1. yarn or npm install react-native-svg
```~.bash
yarn add react-native-svg
npx pod-install
yarn add --dev react-native-svg-transformer
```

2\. Rewrite "metro.config.js" in the root directory where "App.js" is located.

```
const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();
```

3\. You should be able to use it by importing the SVG file and specifying the size in JSX.

```
import Logo from './logo.svg'
/*(omission)*/
<Logo width={100} height={100} />
```
Yes, this is the way as per the official documentation so far.

## Changing colors dynamically1 (for single color)

Just change the fill part of the SVG file to "currentColor" (the same way you change the SVG color in HTML)

```
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect width="300" height="100" fill="#f00"/>
</svg>
```

Change the above to the following.


```
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect width="300" height="100" fill="currentColor"/>
</svg>
```

Set it in style on JSX.

```
<Logo width={100} height={100} style={{color:'#ccc'}}  />
```

## Dynamically changing colors2 (multiple colors, but no more than 5 colors)

This is another way to use SVGR, as described in the react-native-svg-transformer page.


1. Create a file named ".svgrrc" in the root directory where "App.js" is located.
1. Change the fill value of the SVG file to one of the five colors "#000,#f00,#ff0,#ff1,#f11".(In other words, no more than five colors can be changed.)
1. Write ".svgrrc" as follows.

```
{
  "replaceAttrValues": {
    "#000": "{props.aaa}",
    "#00f": "{props.bbb}",
    "#ff0": "{props.ccc}",
  }
}
```

4\. Specify values for JSX.(It is possible to use only one color.)

```
<Logo width="100" height="100" aaa={"#f00"} />
```
## Problems with the SVGR

It did not work properly unless the fill values of the relevant SVG file was a specific number such as "#000".
In conclusion, the SVG color replacement is only for 3 digits of RGB, and the possible replacement strings are as follows.

|RGB|
|-|
|#000|
|#f00|
|#ff0|
|#ff1|
|#f11|

The combination of websafe colors 0,3,6,9,c almost didn't work.(I couldn't believe that "#f0f" and "#0ff" weren't allowed.)
I guess this means that you don't need to dynamically change things that have a lot of colors.


Here are didn't work

```
#fff
#00f
#ccc
#222-999
#11f
#1f1
#1ff
#f01
#f1f
#f12
#0ff
#f01
#ff0
#ff1
#f1f
#3ff
#321
#f03
#90f
#100
#101
```

If I want to change more than five colors, I should probably create a separate SVG file in the first place, but according to the SVGR specification, I should be able to change even six-digit RGB values, and  it should even support regular expressions...

## Sum up

These up to you to decide if that's true.(Same as the other articles.)