Hey folks,
In this article, we will be creating the share feature for an app in React Native using
the following libraries -
First things first !!
node --version
v14.17.6
npm --version
6.14.15
npx react-native -v
10.2.2
Create a new React Native app using the following command -
npx react-native init Share_Project
Remove the template code in
App.js
and ensureApp.js
looks like the following -import React from 'react'; import {View} from 'react-native'; const App = () => { return <View />; }; export default App;
Now, let's install the required libraries -
Run the falling commands in your terminal to install the libraries -
npm i react-native-fs
npm i react-native-share
Make sure the final package.json file of your app looks similar to the following code.
{
"name": "AwesomeProject",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.71.10",
"react-native-fs": "^2.20.0", // Added react-native-fs
"react-native-share": "^8.2.2" // Added react-native-share
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native-community/eslint-config": "^3.2.0",
"@tsconfig/react-native": "^2.0.2",
"@types/jest": "^29.2.1",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.73.9",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "4.8.4"
},
"jest": {
"preset": "react-native"
}
}
You can refer to the docs for the React Native libraries added from this section -
- Once we are done with all libraries, let's create a simple button in the center of the screen.
On clicking this button the text will be shared on Whatsapp. If Whatsapp is not installed on the phone, available share options will be shown to the user.
Create a view and give it styles to occupy the full screen and align the items in the center of the screen.
import React from 'react';
import {Button, View} from 'react-native';
const App = () => {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Button title="Share Now" onPress={() => {}} />
</View>
);
};
export default App;
Create a function onSharePress that will contain the image download and sharing logic, and assign it to the onPress prop of the button.
import React from 'react';
import {Button, View} from 'react-native';
const App = () => {
const onSharePress = () => {};
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Button title="Share Now" onPress={onSharePress} />
</View>
);
};
export default App;
The UI will look similar to the below image.
Let's write our main logic for downloading and sharing, in the onSharePress
function.
Import the libraries in App.js
file
import Share from 'react-native-share';
import RNFS from 'react-native-fs';
Create variables for text, link and Url of the image to be shared.
Url of the image that will be shared -> imageUrl
Message to be shared -> Hi, pls visit my Hashnode profile
Link -> paditya26
const message = 'Hi, pls visit my Hashnode profile';
const imageUrl =
'http://commondatastorage.googleapis.com/codeskulptor-demos/riceracer_assets/img/car_3.png';
const link = 'https://hashnode.com/@paditya26';
Create shareOptions
object inside onSharePress
function, which will be passed to Share.singleShare
function.
const onSharePress = () => {
const shareOptions = {
message: `${message}\n${link}`,
}; /* Creating shareOptions object containing a messageKey
with value `${message}\n${link}` so that the link appears right
below the message when user shares the message on any platform.
*/
};
Wrap download and share logic, inside a try-catch block for error handling.
const onSharePress = () => {
const shareOptions = {
message: `${message}\n${link}`,
};
try {
} catch (error) {
console.log(error);
}
};
Download the image from the image link to a particular location in the app's cache memory.
react-native-fs library gives a downloadFile
function that takes fromUrl
and toFile
as parameters to download the file from fromUrl
and store it in the location specified by toFile. Here the name of the file is given as image.jpg. The downloadFile
returns a promise. .then
and .catch
can be used with a promise to trigger logic if the code has been executed successfully or has failed.
const onSharePress = () => {
const shareOptions = {
message: `${message}\n${link}`,
};
try {
RNFS.downloadFile({
fromUrl: imageUrl,
toFile: `${RNFS.CachesDirectoryPath}/image.jpg`,
})
.promise.then(() => {
})
.catch(err => {
console.log(err);
});
} catch (error) {
console.log(error);
}
};
Read the file in base64 format, from the location where it was stored using the readFile
function of the react-native-fs library.
const onSharePress = () => {
const shareOptions = {
message: `${message}\n${link}`,
};
try {
RNFS.downloadFile({
fromUrl: imageUrl,
toFile: `${RNFS.CachesDirectoryPath}/image.jpg`,
})
.promise.then(() => {
RNFS.readFile(`${RNFS.CachesDirectoryPath}/image.jpg`, 'base64')
.then(res => {
})
.catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
} catch (error) {
console.log(error);
}
};
Once we get the response res
from the readFile
function, set the url
key of the shareOptions
object to `data:image/png;base64,${res}`. This will help load the image on different sharing platforms.
Use the shareSingle
function from the react-native-share library to share the message, link and image on various platforms. Pass shareOptions
object inside the shareSingle
function by using the spread operator (...).
Set social
key inside the shareSingle
functions as Share.Social.WHATSAPP
. This allows the user to share the message, particularly on Whatsapp, if it is installed on the device. If Whatsapp is not installed on the device, this will automatically open other sharing options that are available on the device.
const onSharePress = () => {
const shareOptions = {
message: `${message}\n${link}`,
};
try {
RNFS.downloadFile({
fromUrl: imageUrl,
toFile: `${RNFS.CachesDirectoryPath}/image.jpg`,
})
.promise.then(() => {
RNFS.readFile(`${RNFS.CachesDirectoryPath}/image.jpg`, 'base64')
.then(res => {
shareOptions.url = `data:image/png;base64,${res}`;
Share.shareSingle({
...shareOptions,
social: Share.Social.WHATSAPP,
}).catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
} catch (error) {
console.log(error);
}
};
The final code in App.js
file would look like this.
import React from 'react';
import {Button, Image, View} from 'react-native';
import Share from 'react-native-share';
import RNFS from 'react-native-fs';
const App = () => {
const message = 'Hi, pls visit my Hashnode profile';
const imageUrl =
'http://commondatastorage.googleapis.com/codeskulptor-demos/riceracer_assets/img/car_3.png';
const link = 'https://hashnode.com/@paditya26';
const onSharePress = () => {
const shareOptions = {
message: `${message}\n${link}`,
};
try {
RNFS.downloadFile({
fromUrl: imageUrl,
toFile: `${RNFS.CachesDirectoryPath}/image.jpg`,
})
.promise.then(() => {
RNFS.readFile(`${RNFS.CachesDirectoryPath}/image.jpg`, 'base64')
.then(res => {
shareOptions.url = `data:image/png;base64,${res}`;
Share.shareSingle({
...shareOptions,
social: Share.Social.WHATSAPP,
}).catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
} catch (error) {
console.log(error);
}
};
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Button title="Share Now" onPress={onSharePress} />
</View>
);
};
export default App;
Important Things to Note -
Share.Social
has multiple options available for some common sharing platforms likeShare.Social.WHATSAPP,
Share.Social.Twitter,
etc. Depending on the use case developer needs to choose the correct option.RNFS
has multiple default locations to store files or images likeC RNFS.CachesDirectoryPath,
RNFS.DownloadDirectoryPath
etc. Depending on the use case developer needs to choose the correct option.Some of the features of react-native-fs, react-native-share are available only in Android or IOS.
The above video shows the demo for sharing the message on Whatsapp.
The above video shows the demo for sharing the message when Whatsapp is not installed and other sharing platforms are available.
Voohooooooo!! We have completed the project. Cheers !!
Follow me on Twitter for more tech content on React Native.