Getting Started with React Native
What is SVG and usage of SVG icon:
Scalable Vector Graphics (SVG) is an XML based language for describing two-dimensional vector graphics.
Usage of SVG: -
- SVG images can be rendered in any size without losing any quality.
- File size: - SVG image has a small file size that compresses well.
- Style control: - You can change the styles within your SVG image.
Getting started with React Native:
If you are a beginner in React-Native go with Expo-CLI. npm install -g expo-cli expo init SvgTransformer cd SvgTransformer expo start // you can also use: npm start
How to use SVG file in React Native:
React Native doesn’t support SVG by default, to use SVGs in react native project you need to transform those images into React components by SVGR to display the components. This can be done by using react-native-svg package.
Getting started with react-native-svg:
Install react-native-svg library
If you use React Native version older than 0.60, you need to link react-native-svg
manually
Get start with react-native-svg-transforme
r:
yarn add --dev react-native-svg-transformer || npm install -d react-native-svg-transformer
For Expo SDK v40.0.0 or newerMerge the contents from your project’s metro.config.js
file with this config (create the file if it does not exist already)
metro.config.js:
const { getDefaultConfig } = require("@expo/metro-config");
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts }
} = await getDefaultConfig(__dirname);
return {
transformer: {
babelTransformerPath: require.resolve("react-native-svg-transformer")
},
resolver: {
assetExts: assetExts.filter(ext => ext !== "svg"),
sourceExts: [...sourceExts, "svg"]
}
};
})();
For React Native v0.57 or newer / Expo SDK v31.0.0 or newer, if you are using Expo, merge the contents from your project’s metro.config.js
file with this config (create the file if it does not exist already).
metro.config.js:
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"]
}
};
})();
If you are using Expo, you also need to add this to app.json
:
{
"expo": {
"packagerOpts": {
"config": "metro.config.js",
"sourceExts": [
"expo.ts",
"expo.tsx",
"expo.js",
"expo.jsx",
"ts",
"tsx",
"js",
"jsx",
"json",
"wasm",
"svg"
]
}
}
}
Check here For React Native v0.56 or older / For Expo SDK v30.0.0 or older
Using TypeScript:
If you are using TypeScript, you need to add this to your declarations.d.ts
file (create one if you don’t have one already):
import React from 'react';
declare module "*.svg" {
import { SvgProps } from "react-native-svg";
const content: React.FC<SvgProps>;
export default content;
}
let us Make our hands dirty:
Step-1:-
Download and add an SVG file into your asset folder and import that into your project file. Click the here to download one.
After the downloading SVG image into your project, select your SVG image and change the fill to currentColor
(For some SVG it will be stroke)
It will be available on the end of the path tag.
Step 2:-
After the downloading SVG image into your project, select your SVG image and change the fill to currentColor
(For some SVG it will be stroke)
Initialize 3 states for 3 icons to change the color of the SVG image, for that we can use the useState hook from React. Here initial state will be false.
const [isBlue, setIsBlue] = React.useState(false);
const [isRed, setIsRed] = React.useState(false);
const [isViolet, setIsViolet] = React.useState(false);
Step 3:-
Add a touchable effect using TouchableOpacity inside a parent View and add SVG Image inside the TouchableOpacity
TouchableOpacity is a wrapper for making views respond properly to touches. On press down, the opacity of the wrapped view is decreased, dimming it.
<View style={Styles.container}>
<TouchableOpacity style={Styles.button}>
<WhatsAppIcon
height={50}
width={50}
/>
</TouchableOpacity>
...
</View>
Step 4:-
Now we need to change the color of the SVG Image, for that we can change the state to the opposite of the initial state.
onPress={() => setIsBlue(!isBlue)}
Here we changed the state to the opposite of the current state.
Now we need to change the color of the SVG Image by checking the state of the SVG image here initial color is "#4FCE5D"
(moderate lime green) whenever the user tap on that image the state changes and the corresponding color will be shown.
style ={{ color: isBlue ? "#0000FF" : "#4FCE5D" }}
Step 5:-
Repeat these steps for the remaining 2 images for that wrap your SVG image inside the TouchableOpacity and repeat the steps above mentioned.
Let’s see the final result: Here is the GitHub Link and for more reference react-native-svg-transformer.
Here is the full code:
import React from "react";
import { View, Text, StyleSheet } from "react-native";
import WhatsAppIcon from "../../assets/svg/whatsapp_icon.svg";
import { TouchableOpacity } from "react-native-gesture-handler";
const MainScreen = () => {
const [isBlue, setIsBlue] = React.useState(false);
const [isRed, setIsRed] = React.useState(false);
const [isViolet, setIsViolet] = React.useState(false);
return (
<View style={Styles.container}>
<TouchableOpacity style={Styles.button}>
<WhatsAppIcon
style={[
isBlue
? { color: "#0000FF" }
: { color: "#4FCE5D" },
]}
height={50}
width={50}
onPress={() => {
setIsBlue(!isBlue);
}}
/>
</TouchableOpacity>
<TouchableOpacity style={Styles.button}>
<WhatsAppIcon
style={[
isRed
? {color: "#FF0000" }
: { color: "#4FCE5D" },
]}
height={50}
width={50}
onPress={() => {
setIsRed(!isRed);
}}
/>
</TouchableOpacity>
<TouchableOpacity style={Styles.button}>
<WhatsAppIcon
style={[
isViolet
? { color: "#DA70D6" }
: { color: "#4FCE5D" },
]}
height={50}
width={50}
onPress={() => {
setIsViolet(!isViolet);
}}
/>
</TouchableOpacity>
</View>
);
};
export default MainScreen;
const Styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
},
button: {
flex: 1,
height: "100%",
width: "100%",
alignItems: "center",
justifyContent: "center",
},
});