Bird
Raised Fist0
React Nativemobile~20 mins

Lifting state up in React Native - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Temperature Converter
A screen that converts temperature between Celsius and Fahrenheit. The user can enter a value in either input, and the other input updates automatically.
Target UI
-------------------------
| Temperature Converter  |
|-----------------------|
| Celsius: [        ]    |
| Fahrenheit: [        ] |
|                       |
| (Both inputs update each|
|  other when changed)   |
-------------------------
Two text inputs labeled 'Celsius' and 'Fahrenheit'.
Typing a number in Celsius updates Fahrenheit automatically.
Typing a number in Fahrenheit updates Celsius automatically.
State should be lifted up to a common parent to keep inputs in sync.
Inputs accept only numeric values.
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

export default function TemperatureConverter() {
  // TODO: Add state here

  return (
    <View style={styles.container}>
      <Text style={styles.label}>Celsius:</Text>
      <TextInput
        style={styles.input}
        keyboardType="numeric"
        // TODO: Add value and onChangeText for Celsius
      />

      <Text style={styles.label}>Fahrenheit:</Text>
      <TextInput
        style={styles.input}
        keyboardType="numeric"
        // TODO: Add value and onChangeText for Fahrenheit
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  label: {
    fontSize: 18,
    marginTop: 20,
  },
  input: {
    borderWidth: 1,
    borderColor: '#999',
    padding: 8,
    fontSize: 18,
    borderRadius: 4,
  },
});
Task 1
Task 2
Task 3
Task 4
Solution
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

function toCelsius(fahrenheit) {
  return ((fahrenheit - 32) * 5) / 9;
}

function toFahrenheit(celsius) {
  return (celsius * 9) / 5 + 32;
}

function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  if (Number.isNaN(input)) {
    return '';
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}

export default function TemperatureConverter() {
  const [temperature, setTemperature] = useState('');
  const [scale, setScale] = useState('c');

  const handleCelsiusChange = (text) => {
    setTemperature(text);
    setScale('c');
  };

  const handleFahrenheitChange = (text) => {
    setTemperature(text);
    setScale('f');
  };

  const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
  const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;

  return (
    <View style={styles.container}>
      <Text style={styles.label}>Celsius:</Text>
      <TextInput
        style={styles.input}
        keyboardType="numeric"
        value={celsius}
        onChangeText={handleCelsiusChange}
        accessibilityLabel="Celsius input"
      />

      <Text style={styles.label}>Fahrenheit:</Text>
      <TextInput
        style={styles.input}
        keyboardType="numeric"
        value={fahrenheit}
        onChangeText={handleFahrenheitChange}
        accessibilityLabel="Fahrenheit input"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  label: {
    fontSize: 18,
    marginTop: 20,
  },
  input: {
    borderWidth: 1,
    borderColor: '#999',
    padding: 8,
    fontSize: 18,
    borderRadius: 4,
  },
});

We keep the temperature value and the scale (which input was last changed) in the parent component's state. When the user types in one input, we update the temperature and scale. Then we convert the temperature to the other scale for the other input. This way, both inputs stay in sync.

We use helper functions to convert between Celsius and Fahrenheit. The inputs accept only numeric values and show the converted temperature rounded to three decimals.

This pattern is called "lifting state up" because the shared state lives in the common parent, not inside each input separately.

Final Result
Completed Screen
-------------------------
| Temperature Converter  |
|-----------------------|
| Celsius: [  25.0   ]   |
| Fahrenheit: [ 77.0  ]  |
|                       |
| (Typing in one input   |
|  updates the other)    |
-------------------------
Typing a number in the Celsius input updates the Fahrenheit input automatically.
Typing a number in the Fahrenheit input updates the Celsius input automatically.
Only numeric input is accepted in both fields.
Stretch Goal
Add a clear button that resets both inputs to empty.
💡 Hint
Add a Button component below inputs that sets temperature state to empty string and scale to 'c' when pressed.

Practice

(1/5)
1. What is the main purpose of lifting state up in React Native?
easy
A. To create multiple independent states in child components
B. To move shared state to a common parent component so children can access it
C. To store state only inside child components without sharing
D. To avoid using props for data sharing between components

Solution

  1. Step 1: Understand the concept of shared state

    Lifting state up means moving state to a common parent so multiple children can use it.
  2. Step 2: Identify the purpose of lifting state up

    This helps keep data consistent and allows children to communicate through the parent.
  3. Final Answer:

    To move shared state to a common parent component so children can access it -> Option B
  4. Quick Check:

    Lifting state up = shared parent state [OK]
Hint: Shared data lives in parent to sync children easily [OK]
Common Mistakes:
  • Thinking each child should have its own separate state
  • Believing lifting state up removes the need for props
  • Confusing lifting state up with component styling
2. Which of the following is the correct way to pass a state update function from a parent to a child component in React Native?
easy
A.
B.
C.
D.

Solution

  1. Step 1: Identify what to pass as prop

    The parent passes a function to update state, not the state value or setState method directly.
  2. Step 2: Choose the correct syntax

    Passing updateStateFunction as a prop is correct to allow child to call it.
  3. Final Answer:

    <Child updateState={updateStateFunction} /> -> Option C
  4. Quick Check:

    Pass update function as prop = <Child updateState={updateStateFunction} /> [OK]
Hint: Pass functions, not state or setState directly [OK]
Common Mistakes:
  • Passing the entire state object instead of a function
  • Passing setState method directly without binding
  • Passing state value instead of update function
3. Given the code below, what will be the output when the button in Child is pressed?
function Parent() {
  const [count, setCount] = React.useState(0);
  return (
    <>
      <Child count={count} increment={() => setCount(count + 1)} />
      <Text>Count: {count}</Text>
    </>
  );
}

function Child({ count, increment }) {
  return <Button title={`Add`} onPress={increment} />;
}
medium
A. The app will crash due to incorrect state update
B. The count will always stay 0 regardless of button presses
C. The button will not respond to presses
D. The count displayed will increase by 1 each time the button is pressed

Solution

  1. Step 1: Understand state and props flow

    The Parent holds the count state and passes it plus an increment function to Child.
  2. Step 2: Analyze what happens on button press

    Pressing the button calls increment, which updates count by adding 1.
  3. Final Answer:

    The count displayed will increase by 1 each time the button is pressed -> Option D
  4. Quick Check:

    State update via lifted function increments count [OK]
Hint: Button calls parent's update function to increase count [OK]
Common Mistakes:
  • Thinking count won't update because it's passed as prop
  • Assuming setCount is not called correctly
  • Confusing local and lifted state
4. Identify the error in this lifting state up example:
function Parent() {
  const [text, setText] = React.useState('');
  return <Child text={text} setText={setText()} />;
}

function Child({ text, setText }) {
  return <TextInput value={text} onChangeText={setText} />;
}
medium
A. setText is called immediately instead of passing the function
B. text state is not initialized properly
C. Child component should not receive setText as prop
D. TextInput should not use onChangeText prop

Solution

  1. Step 1: Check how setText is passed as prop

    In Parent, setText={setText()} calls setText immediately instead of passing the function.
  2. Step 2: Correct way to pass setText

    It should be setText={setText} to pass the function reference.
  3. Final Answer:

    setText is called immediately instead of passing the function -> Option A
  4. Quick Check:

    Pass function reference, not call it [OK]
Hint: Pass function, don't call it when passing as prop [OK]
Common Mistakes:
  • Calling setState function instead of passing it
  • Confusing state value with update function
  • Ignoring React hooks rules
5. You have two sibling components, TemperatureInputCelsius and TemperatureInputFahrenheit, that need to share temperature data. How should you use lifting state up to keep both inputs in sync?
hard
A. Move the temperature state to their common parent and pass value and update functions as props
B. Keep separate states in each sibling and update independently
C. Store temperature state only in one sibling and let the other read it directly
D. Use global variables outside React components to share temperature

Solution

  1. Step 1: Identify the need for shared state

    Both siblings need to reflect the same temperature, so state must be shared.
  2. Step 2: Apply lifting state up

    Move temperature state to their common parent and pass it plus update functions down as props.
  3. Step 3: Avoid incorrect approaches

    Separate states cause inconsistency; global variables break React's data flow.
  4. Final Answer:

    Move the temperature state to their common parent and pass value and update functions as props -> Option A
  5. Quick Check:

    Lift shared state to parent for syncing siblings [OK]
Hint: Parent holds shared state; siblings get props and update functions [OK]
Common Mistakes:
  • Keeping separate states causing out-of-sync inputs
  • Trying to share state via global variables
  • Passing state only to one sibling
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard