------------------------- | File Manager | ------------------------- | Filename: [__________] | | | | Content: | | [ ] | | [ ] | | [ ] | | | | [Save] [Read] [Delete]| -------------------------
File system access in React Native - Mini App: Build & Ship
import React, { useState } from 'react'; import { View, TextInput, Button, Alert, StyleSheet, Text } from 'react-native'; import * as FileSystem from 'expo-file-system'; export default function FileManager() { const [filename, setFilename] = useState(''); const [content, setContent] = useState(''); // TODO: Implement saveFile function // TODO: Implement readFile function // TODO: Implement deleteFile function return ( <View style={styles.container}> <Text style={styles.label}>Filename:</Text> <TextInput style={styles.input} value={filename} onChangeText={setFilename} placeholder="Enter filename" accessibilityLabel="Filename input" /> <Text style={styles.label}>Content:</Text> <TextInput style={styles.textArea} value={content} onChangeText={setContent} placeholder="Enter file content" multiline accessibilityLabel="File content input" /> <View style={styles.buttonRow}> <Button title="Save" onPress={() => {}} /> <Button title="Read" onPress={() => {}} /> <Button title="Delete" onPress={() => {}} /> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, padding: 20, backgroundColor: '#fff' }, label: { fontSize: 16, marginBottom: 4 }, input: { borderWidth: 1, borderColor: '#ccc', padding: 8, marginBottom: 12, borderRadius: 4 }, textArea: { borderWidth: 1, borderColor: '#ccc', padding: 8, height: 100, textAlignVertical: 'top', borderRadius: 4 }, buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 } });
import React, { useState } from 'react'; import { View, TextInput, Button, Alert, StyleSheet, Text } from 'react-native'; import * as FileSystem from 'expo-file-system'; export default function FileManager() { const [filename, setFilename] = useState(''); const [content, setContent] = useState(''); const getFileUri = () => { if (!filename) return null; return FileSystem.documentDirectory + filename; }; const saveFile = async () => { const fileUri = getFileUri(); if (!fileUri) { Alert.alert('Error', 'Please enter a filename'); return; } try { await FileSystem.writeAsStringAsync(fileUri, content); Alert.alert('Success', 'File saved successfully'); } catch (e) { Alert.alert('Error', 'Failed to save file'); } }; const readFile = async () => { const fileUri = getFileUri(); if (!fileUri) { Alert.alert('Error', 'Please enter a filename'); return; } try { const fileContent = await FileSystem.readAsStringAsync(fileUri); setContent(fileContent); Alert.alert('Success', 'File read successfully'); } catch (e) { Alert.alert('Error', 'Failed to read file'); } }; const deleteFile = async () => { const fileUri = getFileUri(); if (!fileUri) { Alert.alert('Error', 'Please enter a filename'); return; } try { await FileSystem.deleteAsync(fileUri); setContent(''); Alert.alert('Success', 'File deleted successfully'); } catch (e) { Alert.alert('Error', 'Failed to delete file'); } }; return ( <View style={styles.container}> <Text style={styles.label}>Filename:</Text> <TextInput style={styles.input} value={filename} onChangeText={setFilename} placeholder="Enter filename" accessibilityLabel="Filename input" /> <Text style={styles.label}>Content:</Text> <TextInput style={styles.textArea} value={content} onChangeText={setContent} placeholder="Enter file content" multiline accessibilityLabel="File content input" /> <View style={styles.buttonRow}> <Button title="Save" onPress={saveFile} /> <Button title="Read" onPress={readFile} /> <Button title="Delete" onPress={deleteFile} /> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, padding: 20, backgroundColor: '#fff' }, label: { fontSize: 16, marginBottom: 4 }, input: { borderWidth: 1, borderColor: '#ccc', padding: 8, marginBottom: 12, borderRadius: 4 }, textArea: { borderWidth: 1, borderColor: '#ccc', padding: 8, height: 100, textAlignVertical: 'top', borderRadius: 4 }, buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 } });
We use Expo's FileSystem API to handle file operations in the app's document directory. The getFileUri function builds the full path for the file using the filename input. The saveFile function writes the content to this file path. The readFile function reads the file content and updates the content state to show it in the text area. The deleteFile function removes the file and clears the content. Each function shows an alert to inform the user about success or failure. Buttons are connected to these functions to trigger the actions. Accessibility labels are added for screen readers. The UI uses simple inputs and buttons arranged vertically with spacing.
------------------------- | File Manager | ------------------------- | Filename: [myfile.txt] | | | | Content: | | [Hello, this is a ]| | [sample file content. ]| | [ ] | | | | [Save] [Read] [Delete]| -------------------------
Practice
react-native-fs in a React Native app?Solution
Step 1: Understand the role of
This library is designed to provide file system access in React Native apps.react-native-fsStep 2: Identify the correct functionality
It allows reading and writing files on the device, unlike UI or network libraries.Final Answer:
To read and write files on the device's file system -> Option AQuick Check:
File system access = read/write files [OK]
- Confusing file system access with UI components
- Thinking it manages navigation or network calls
- Assuming it handles permissions automatically
react-native-fs in a React Native file?Solution
Step 1: Recall ES6 import syntax for default exports
react-native-fsexports a default object, so useimport RNFS from 'react-native-fs';.Step 2: Check other options
const RNFS = require('react-native-fs'); uses CommonJS require (valid but less common in modern React Native). import { RNFS } from 'react-native-fs'; incorrectly destructures. import * as RNFS from 'react-native-fs'; imports all as namespace but is not the recommended style here.Final Answer:
import RNFS from 'react-native-fs'; -> Option BQuick Check:
Default import syntax = import RNFS from 'react-native-fs'; [OK]
- Using destructuring import for default export
- Mixing require and import styles
- Using namespace import unnecessarily
test.txt contains the text "Hello World"?
import RNFS from 'react-native-fs';
RNFS.readFile(RNFS.DocumentDirectoryPath + '/test.txt', 'utf8')
.then(contents => console.log(contents))
.catch(err => console.log('Error:', err.message));Solution
Step 1: Understand readFile behavior
ThereadFilemethod reads the file content as a string when encoding is 'utf8'.Step 2: Check file content and output
The file contains "Hello World", so the promise resolves and logs this string.Final Answer:
"Hello World" -> Option DQuick Check:
readFile with utf8 returns file text [OK]
- Assuming readFile returns a buffer or object
- Expecting error if file exists
- Ignoring promise and expecting synchronous output
import RNFS from 'react-native-fs';
RNFS.writeFile('/path/to/file.txt', 'Sample text', 'utf8')
.then(() => console.log('File written'))
.catch(error => console.log('Write error:', error));Solution
Step 1: Check file path usage
In React Native, absolute paths like '/path/to/file.txt' are invalid; useRNFS.DocumentDirectoryPathor similar directory constants.Step 2: Validate other parameters
Encoding 'utf8' is valid, writeFile returns a promise, and text can be a string.Final Answer:
The file path should use RNFS.DocumentDirectoryPath or similar, not an absolute string -> Option AQuick Check:
Use RNFS paths, not absolute strings [OK]
- Using absolute file paths directly
- Misunderstanding writeFile return type
- Passing wrong data types for text
react-native-fs?Solution
Step 1: Handle permissions properly
On mobile devices, storage permission must be requested before file operations.Step 2: Use safe file paths and encoding
UseRNFS.DocumentDirectoryPathfor file location and specify encoding like 'utf8' for writing and reading.Step 3: Implement error handling
Use promises withthenandcatchto handle success and errors safely.Final Answer:
Request storage permission, write file using RNFS.DocumentDirectoryPath, then read file with error handling -> Option CQuick Check:
Permissions + RNFS paths + error handling = Request storage permission, write file using RNFS.DocumentDirectoryPath, then read file with error handling [OK]
- Skipping permission requests
- Using hardcoded absolute paths
- Ignoring promise errors
- Using wrong encoding for text files
Ready to prove it?
Pass the test and this pattern moves unknown
