How to Download and Display a file in React Native
React Native does not currently offer full support for downloading and showing a file. The approach in this article shows you how to download and display a file using the `react-native-fs` and `react-native-webview` libraries respectively.
In this example, the file is of a PDF format, however, the same approach can be used for images or other text file formats.
Prerequisites:
A working React Native App. Not sure how to do this? Checkout the setup instructions on the React Native Website.
Downloading the file
Install react-native-fs:
yarn add react-native-fs
or
npm install react-native-fs
If you’re using React Native version 0.60.0 or higher, it a does auto-linking for you. If not, check the extra setup instructions on react-native-fs page.
Install the CocoaPods dependencies (iOS specific):
cd ios && pod install
Downloading the file:
In this example, I will be retrieving a PDF file from an API endpoint using the downloadFile
function from react-native-fs. This function has two required parameters — fromUrl
and toFile
, along with several other optional ones. I created an async function downloadPDF
which requires a url
and fileName
. It also contains a basic header with an authorization token and content-type.
React-native-fs’ DocumentDirectoryPath
provides the Android or iOS where documents are stored. You can change this to your customised path if you wish.
downloadPDF = async (url: string, fileName: string): Promise<any> =>{
//Define path to store file along with the extensionconst path = `${DocumentDirectoryPath}/${fileName}.pdf`;const headers = {
'Accept': 'application/pdf',
'Content-Type': 'application/pdf',
'Authorization': `Bearer [token]`
}//Define optionsconst options: DownloadFileOptions = {
fromUrl: [baseUrl] + url,
toFile: path,
headers: headers
}//Call downloadFileconst response = await downloadFile(options);return response.promise.then(async res =>
//Transform response
if(res && res.statusCode === 200 && res.bytesWritten > 0 &&
res.path){
doSomething(res)
}else{
logError(res)
}};
The response from downloadFile
contains statusCode
, jobId
and bytesWritten
. To know if a request is successful, check whether the statusCode
is 200
and the bytesWritten
> 0
. It is important to check both values because, I found it returning 200
even when no files were written.
I saved the path
in the Redux’s state to later retrieve the file.
Opening the saved file in a WebView
Install react-native-webview:
yarn add react-native-webview
or
npm install react-native-webview
Again, install the CocoaPods dependencies (iOS specific):
cd ios && pod install
Implementing the WebView:
Create a React Funcional Component containing a WebView
.
const WebViewComponent: React.FunctionComponent = ({ navigation, route}: any): JSX.Element => (<WebView
source={{ uri: "file://"+ path}}
style={{ flex: 1 }}
originWhitelist={["*"]}
/>)};export default WebViewComponent;
The WebView
source’s URI should point to file://
+ pathToFile
. Don’t forget to include the style
property and set flex:1
as shown above.