0
0
React Nativemobile~20 mins

SecureStore for sensitive data in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Secure Data Storage
This screen lets users save and retrieve a secret message securely using SecureStore.
Target UI
┌───────────────────────────────┐
│ Secure Data Storage            │
├───────────────────────────────┤
│ Secret Message:               │
│ [__________________________]  │
│                               │
│ [Save Secret]  [Load Secret]  │
│                               │
│ Loaded Secret:                │
│ [__________________________]  │
└───────────────────────────────┘
Add a TextInput for user to enter a secret message.
Add a 'Save Secret' button that saves the message securely using SecureStore.
Add a 'Load Secret' button that retrieves the saved message and displays it.
Show the loaded secret below the buttons.
Handle errors gracefully with alerts.
Use React Native functional components and hooks.
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, Button, Alert, StyleSheet } from 'react-native';
import * as SecureStore from 'expo-secure-store';

export default function SecureDataScreen() {
  const [secret, setSecret] = useState('');
  const [loadedSecret, setLoadedSecret] = useState('');

  // TODO: Implement saveSecret function

  // TODO: Implement loadSecret function

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Secret Message:</Text>
      <TextInput
        style={styles.input}
        value={secret}
        onChangeText={setSecret}
        placeholder="Enter your secret"
        secureTextEntry={true}
        accessibilityLabel="Secret message input"
      />
      <View style={styles.buttonRow}>
        <Button title="Save Secret" onPress={() => {}} />
        <Button title="Load Secret" onPress={() => {}} />
      </View>
      <Text style={styles.title}>Loaded Secret:</Text>
      <Text style={styles.loadedText} accessibilityLabel="Loaded secret text">{loadedSecret}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, justifyContent: 'center' },
  title: { fontSize: 18, marginBottom: 8 },
  input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom: 12, borderRadius: 4 },
  buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 },
  loadedText: { fontSize: 16, color: '#333' }
});
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, Button, Alert, StyleSheet } from 'react-native';
import * as SecureStore from 'expo-secure-store';

export default function SecureDataScreen() {
  const [secret, setSecret] = useState('');
  const [loadedSecret, setLoadedSecret] = useState('');

  async function saveSecret() {
    try {
      if (!secret) {
        Alert.alert('Please enter a secret to save.');
        return;
      }
      await SecureStore.setItemAsync('userSecret', secret);
      Alert.alert('Secret saved securely!');
      setSecret('');
    } catch (error) {
      Alert.alert('Error saving secret:', error.message);
    }
  }

  async function loadSecret() {
    try {
      const result = await SecureStore.getItemAsync('userSecret');
      if (result) {
        setLoadedSecret(result);
      } else {
        Alert.alert('No secret found.');
        setLoadedSecret('');
      }
    } catch (error) {
      Alert.alert('Error loading secret:', error.message);
    }
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Secret Message:</Text>
      <TextInput
        style={styles.input}
        value={secret}
        onChangeText={setSecret}
        placeholder="Enter your secret"
        secureTextEntry={true}
        accessibilityLabel="Secret message input"
      />
      <View style={styles.buttonRow}>
        <Button title="Save Secret" onPress={saveSecret} />
        <Button title="Load Secret" onPress={loadSecret} />
      </View>
      <Text style={styles.title}>Loaded Secret:</Text>
      <Text style={styles.loadedText} accessibilityLabel="Loaded secret text">{loadedSecret}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, justifyContent: 'center' },
  title: { fontSize: 18, marginBottom: 8 },
  input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom: 12, borderRadius: 4 },
  buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 },
  loadedText: { fontSize: 16, color: '#333' }
});

We use expo-secure-store to save and load sensitive data securely on the device. The saveSecret function saves the entered secret with setItemAsync. It checks if the input is empty and shows an alert if so. The loadSecret function retrieves the saved secret with getItemAsync and updates the displayed text. Both functions handle errors by showing alerts. The UI uses accessible labels and secure text entry for privacy.

Final Result
Completed Screen
┌───────────────────────────────┐
│ Secure Data Storage            │
├───────────────────────────────┤
│ Secret Message:               │
│ [***************         ]    │
│                               │
│ [Save Secret]  [Load Secret]  │
│                               │
│ Loaded Secret:                │
│ [My secret message       ]    │
└───────────────────────────────┘
User types a secret message in the input field.
Tapping 'Save Secret' stores the message securely and clears the input.
Tapping 'Load Secret' retrieves and shows the saved secret below.
If no secret is saved, an alert informs the user.
Errors during save/load show alerts.
Stretch Goal
Add a button to delete the saved secret securely.
💡 Hint
Use SecureStore.deleteItemAsync with the same key to remove the secret.