0
0
React Nativemobile~20 mins

Profiling with Flipper in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Performance Profiler Setup
This screen helps you set up Flipper profiling in a React Native app to monitor performance and debug UI issues.
Target UI
┌───────────────────────────────┐
│ Performance Profiler Setup     │
├───────────────────────────────┤
│ [ ] Enable Flipper Profiling   │
│                               │
│ [Start Profiling] [Stop]       │
│                               │
│ Logs:                         │
│ ----------------------------- │
│                               │
│                               │
└───────────────────────────────┘
Add a toggle switch to enable or disable Flipper profiling.
Add two buttons: 'Start Profiling' and 'Stop' to control profiling state.
Display a simple log area that shows profiling status messages.
Use React Native components and hooks to manage state.
Ensure the UI is accessible with proper labels.
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, Switch, Button, ScrollView, StyleSheet } from 'react-native';

export default function ProfilerSetup() {
  const [isEnabled, setIsEnabled] = useState(false);
  const [logs, setLogs] = useState([]);

  // TODO: Add handlers for toggling and buttons

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Performance Profiler Setup</Text>
      <View style={styles.row}>
        <Switch
          value={isEnabled}
          onValueChange={(value) => {
            setIsEnabled(value);
            // TODO: Add log update
          }}
          accessibilityLabel="Enable Flipper Profiling"
        />
        <Text style={styles.label}>Enable Flipper Profiling</Text>
      </View>
      <View style={styles.buttonRow}>
        <Button title="Start Profiling" onPress={() => { /* TODO */ }} />
        <Button title="Stop" onPress={() => { /* TODO */ }} />
      </View>
      <Text style={styles.logTitle}>Logs:</Text>
      <ScrollView style={styles.logBox}>
        {/* TODO: Render logs here */}
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: '#fff' },
  title: { fontSize: 20, fontWeight: 'bold', marginBottom: 20 },
  row: { flexDirection: 'row', alignItems: 'center', marginBottom: 20 },
  label: { marginLeft: 10, fontSize: 16 },
  buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 },
  logTitle: { fontWeight: 'bold', fontSize: 16, marginBottom: 10 },
  logBox: { borderWidth: 1, borderColor: '#ccc', height: 150, padding: 10, backgroundColor: '#f9f9f9' }
});
Task 1
Task 2
Task 3
Solution
React Native
import React, { useState } from 'react';
import { View, Text, Switch, Button, ScrollView, StyleSheet } from 'react-native';

export default function ProfilerSetup() {
  const [isEnabled, setIsEnabled] = useState(false);
  const [logs, setLogs] = useState([]);

  const addLog = (message) => {
    setLogs((prevLogs) => [message, ...prevLogs]);
  };

  const toggleSwitch = (value) => {
    setIsEnabled(value);
    addLog(`Profiling ${value ? 'enabled' : 'disabled'}`);
  };

  const startProfiling = () => {
    if (isEnabled) {
      addLog('Profiling started');
    } else {
      addLog('Enable profiling first');
    }
  };

  const stopProfiling = () => {
    if (isEnabled) {
      addLog('Profiling stopped');
    } else {
      addLog('Profiling is not enabled');
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Performance Profiler Setup</Text>
      <View style={styles.row}>
        <Switch
          value={isEnabled}
          onValueChange={toggleSwitch}
          accessibilityLabel="Enable Flipper Profiling"
        />
        <Text style={styles.label}>Enable Flipper Profiling</Text>
      </View>
      <View style={styles.buttonRow}>
        <Button title="Start Profiling" onPress={startProfiling} accessibilityLabel="Start Profiling button" />
        <Button title="Stop" onPress={stopProfiling} accessibilityLabel="Stop Profiling button" />
      </View>
      <Text style={styles.logTitle}>Logs:</Text>
      <ScrollView style={styles.logBox} accessibilityLabel="Profiling logs">
        {logs.length === 0 ? (
          <Text>No logs yet</Text>
        ) : (
          logs.map((log, index) => (
            <Text key={index} style={styles.logText}>{log}</Text>
          ))
        )}
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: '#fff' },
  title: { fontSize: 20, fontWeight: 'bold', marginBottom: 20 },
  row: { flexDirection: 'row', alignItems: 'center', marginBottom: 20 },
  label: { marginLeft: 10, fontSize: 16 },
  buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 },
  logTitle: { fontWeight: 'bold', fontSize: 16, marginBottom: 10 },
  logBox: { borderWidth: 1, borderColor: '#ccc', height: 150, padding: 10, backgroundColor: '#f9f9f9' },
  logText: { fontSize: 14, marginBottom: 4 }
});

We use React Native's useState hook to keep track of whether profiling is enabled and to store log messages.

The toggleSwitch function updates the enabled state and adds a log message about the change.

The startProfiling and stopProfiling functions check if profiling is enabled before adding appropriate log messages.

The logs are displayed in a scrollable area, showing the most recent messages at the top.

Accessibility labels are added to controls for screen reader support.

Final Result
Completed Screen
┌───────────────────────────────┐
│ Performance Profiler Setup     │
├───────────────────────────────┤
│ [x] Enable Flipper Profiling   │
│                               │
│ [Start Profiling] [Stop]       │
│                               │
│ Logs:                         │
│ ----------------------------- │
│ Profiling started             │
│ Profiling enabled             │
│                               │
└───────────────────────────────┘
Tapping the switch toggles profiling on or off and logs the change.
Pressing 'Start Profiling' logs 'Profiling started' if enabled, otherwise prompts to enable first.
Pressing 'Stop' logs 'Profiling stopped' if enabled, otherwise informs profiling is not enabled.
Logs appear in the scrollable area with newest messages on top.
Stretch Goal
Add a button to clear all logs from the log area.
💡 Hint
Create a 'Clear Logs' button that sets the logs state to an empty array when pressed.