----------------------------- | State Management Demo | |---------------------------| | useState Counter: 0 | | [Increment] | | | | useReducer Counter: 0 | | [Increment] | -----------------------------
State management comparison in React Native - Mini App: Build & Ship
import React, { useState, useReducer } from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; export default function StateManagementDemo() { // TODO: Add useState counter state here // TODO: Add useReducer counter state here return ( <View style={styles.container}> {/* TODO: Add useState counter UI here */} {/* TODO: Add useReducer counter UI here */} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, counterContainer: { marginVertical: 20, width: '80%', alignItems: 'center', }, counterText: { fontSize: 24, marginBottom: 10, }, });
import React, { useState, useReducer } from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; default: return state; } } export default function StateManagementDemo() { const [countUseState, setCountUseState] = useState(0); const [stateUseReducer, dispatch] = useReducer(reducer, { count: 0 }); return ( <View style={styles.container}> <View style={styles.counterContainer} accessible accessibilityLabel="useState counter section"> <Text style={styles.counterText}>useState Counter: {countUseState}</Text> <Button title="Increment" onPress={() => setCountUseState(countUseState + 1)} accessibilityLabel="Increment useState counter" /> </View> <View style={styles.counterContainer} accessible accessibilityLabel="useReducer counter section"> <Text style={styles.counterText}>useReducer Counter: {stateUseReducer.count}</Text> <Button title="Increment" onPress={() => dispatch({ type: 'increment' })} accessibilityLabel="Increment useReducer counter" /> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, counterContainer: { marginVertical: 20, width: '80%', alignItems: 'center', }, counterText: { fontSize: 24, marginBottom: 10, }, });
We use useState to manage the first counter because it is simple and straightforward for a single value. The countUseState variable holds the current count, and setCountUseState updates it.
For the second counter, we use useReducer which is useful when state logic is more complex or involves multiple actions. Here, the reducer function handles an 'increment' action to increase the count. The dispatch function sends actions to the reducer.
Both counters have their own increment buttons that update their respective states independently. The layout uses View containers with styles for spacing and alignment. Accessibility labels are added for screen readers.
----------------------------- | State Management Demo | |---------------------------| | useState Counter: 0 | | [Increment] | | | | useReducer Counter: 0 | | [Increment] | -----------------------------
Practice
Solution
Step 1: Understand local state needs
Local state means data used only inside one component, like a toggle or input value.Step 2: Match state method to simplicity
useStateis designed for simple, local state inside functional components.Final Answer:
useState-> Option BQuick Check:
Simple local state =useState[OK]
- Choosing Redux for simple local state
- Confusing Context API with local state
- Thinking MobX is simpler than useState
useState in React Native?Solution
Step 1: Recall useState syntax
The correct syntax uses array destructuring: const [value, setter] = useState(initialValue);Step 2: Check each option
const [count, setCount] = useState(0); matches the correct syntax exactly.Final Answer:
const [count, setCount] = useState(0); -> Option DQuick Check:
useState syntax = const [value, setter] = useState(initial) [OK]
- Using let or var instead of const
- Not using array destructuring
- Trying to declare state with 'state' keyword
const [count, setCount] = useState(0); setCount(count + 1); setCount(count + 1); console.log(count);
Solution
Step 1: Understand state updates are asynchronous
Calling setCount twice with count + 1 uses the same stale value of count (0), so both setCount calls set count to 1.Step 2: Check console.log output
console.log(count) runs before state updates complete, so it logs the initial value 0.Final Answer:
0 -> Option AQuick Check:
State updates async, console logs old value [OK]
- Expecting count to be 2 immediately
- Thinking setCount updates synchronously
- Ignoring that console.log runs before update
const [items, setItems] = useState([]);
function addItem(newItem) {
items.push(newItem);
setItems(items);
}Solution
Step 1: Check how state is updated
The code mutates the existing array with push, which is not allowed because state must be immutable.Step 2: Understand correct update method
Instead, create a new array copy with the new item and pass it to setItems.Final Answer:
Directly mutating state array before setItems -> Option AQuick Check:
State must be immutable; don't mutate arrays [OK]
- Mutating arrays or objects directly
- Thinking useState can't hold arrays
- Calling setItems with no arguments
Solution
Step 1: Identify need for shared state
Login status must be accessible across multiple screens, so state must be shared globally.Step 2: Choose appropriate state management
React Context API allows sharing state across components without prop drilling, ideal for global data like login status.Final Answer:
Use React Context API to share login state globally -> Option CQuick Check:
Shared state across screens = Context API [OK]
- Using separate useState in each screen causing inconsistent state
- Trying to store state in local variables
- Confusing styles with state
Ready to prove it?
Pass the test and this pattern moves unknown
