0
0
React Nativemobile~20 mins

useCallback optimization in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Counter with useCallback
A simple counter app that uses useCallback to optimize button press handlers and avoid unnecessary re-renders.
Target UI
Counter with useCallback Optimization

+-------------------------+
| Count: 0                |
|                         |
| [Increment] [Decrement] |
+-------------------------+
Display a count number starting at 0
Two buttons: Increment and Decrement
Use useCallback to memoize the increment and decrement functions
Buttons should update the count correctly
Avoid unnecessary re-renders of buttons by using React.memo
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const CounterScreen = () => {
  const [count, setCount] = useState(0);

  // TODO: Use useCallback to memoize increment and decrement functions

  return (
    <View style={styles.container}>
      <Text style={styles.countText}>Count: {count}</Text>
      <View style={styles.buttonRow}>
        <Button title="Increment" onPress={() => setCount(count + 1)} />
        <Button title="Decrement" onPress={() => setCount(count - 1)} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  countText: { fontSize: 32, marginBottom: 20 },
  buttonRow: { flexDirection: 'row', width: '60%', justifyContent: 'space-around' },
});

export default CounterScreen;
Task 1
Task 2
Task 3
Task 4
Solution
React Native
import React, { useState, useCallback, memo } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const MemoButton = memo(({ title, onPress }) => {
  return <Button title={title} onPress={onPress} />;
});

const CounterScreen = () => {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount(c => c + 1);
  }, []);

  const decrement = useCallback(() => {
    setCount(c => c - 1);
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.countText}>Count: {count}</Text>
      <View style={styles.buttonRow}>
        <MemoButton title="Increment" onPress={increment} />
        <MemoButton title="Decrement" onPress={decrement} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  countText: { fontSize: 32, marginBottom: 20 },
  buttonRow: { flexDirection: 'row', width: '60%', justifyContent: 'space-around' },
});

export default CounterScreen;

We use useCallback to create increment and decrement functions that do not change on every render. This helps React avoid re-rendering child components that depend on these functions.

We also wrap the Button component inside a MemoButton using React.memo. This means the buttons only re-render if their props change.

Using setCount(c => c + 1) inside the callbacks ensures we always update the latest count value without needing to add count as a dependency.

This optimization is useful in bigger apps to improve performance by reducing unnecessary renders.

Final Result
Completed Screen
Counter with useCallback Optimization

+-------------------------+
| Count: 0                |
|                         |
| [Increment] [Decrement] |
+-------------------------+
Tapping Increment increases the count by 1
Tapping Decrement decreases the count by 1
Buttons do not re-render unnecessarily when count changes
Stretch Goal
Add a Reset button that resets the count to zero using useCallback
💡 Hint
Create a memoized reset function with useCallback and add a new MemoButton for Reset