DEV Community

kurokky(黒木シンタロー)
kurokky(黒木シンタロー)

Posted on • Edited on

How to display SVG files and change colors dynamically in React Native.

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", but I continue to use "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
yarn add react-native-svg
npx pod-install
yarn add --dev react-native-svg-transformer
Enter fullscreen mode Exit fullscreen mode

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"]
    }
  };
})();
Enter fullscreen mode Exit fullscreen mode

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} />
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Set it in style on JSX.

<Logo width={100} height={100} style={{color:'#ccc'}}  />
Enter fullscreen mode Exit fullscreen mode

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.
  2. 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.)
  3. Write ".svgrrc" as follows.
{
  "replaceAttrValues": {
    "#000": "{props.aaa}",
    "#00f": "{props.bbb}",
    "#ff0": "{props.ccc}",
  }
}
Enter fullscreen mode Exit fullscreen mode

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

<Logo width="100" height="100" aaa={"#f00"} />
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.)

Top comments (1)

Collapse
 
alexikm profile image
Alex Mouradian

Thanks a lot :)