CodeBlanks Logo Icon CodeBlanks

Putting it together

Combine all parts into a working weather app.

Putting it all together

In the final step we combine every part: the app skeleton, the weather state, the temperature and condition display, and the city picker. We will also add a pull-to-refresh feature.

From the ScrollView and RefreshControl groups you remember: <RefreshControl refreshing={'{refreshing}'} onRefresh={'{handleRefresh}'} /> does pull-to-refresh. The refreshing state drives the spinner; handleRefresh re-fetches the data.

In this project we do not fetch from a network; we use setTimeout to flip setRefreshing(false) after two seconds and give the refresh feel. In a real app this is where a network request would happen.

Final touches

Now there are two tasks. First combine the Picker and the weather card on the same screen; then wrap the whole View in a ScrollView and add a refreshControl.

In the first task put the Picker below the card. selectedValue and onValueChange are already defined; just fix the position.

In the second task replace the outer shell with a <ScrollView>. Give its refreshControl prop a <RefreshControl refreshing={'{refreshing}'} onRefresh={'{handleRefresh}'} />. Define refreshing with useState(false) and a handleRefresh that flips it back to false after two seconds via setTimeout.

Practice Combine the card and city picker

In the App component, show the weather card and Picker together. Card on top, Picker below. Use a getWeather function and a WEATHER_BY_CITY object. Add at least two <Picker.Item> tags. Export the App function.

Starter code

App.js
import { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Picker } from '@react-native-picker/picker';

// write WEATHER_BY_CITY, getWeather and App here

Sample solution

App.js
import { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Picker } from '@react-native-picker/picker';

const WEATHER_BY_CITY = {
  'London': { city: 'London', temp: 14, condition: 'Cloudy' },
  'Manchester': { city: 'Manchester', temp: 12, condition: 'Rainy' }
};
const getWeather = (city) => WEATHER_BY_CITY[city] || WEATHER_BY_CITY['London'];

function App() {
  const [weather, setWeather] = useState(getWeather('London'));
  return (
    <View style={styles.container}>
      <Text style={styles.city}>{weather.city}</Text>
      <Text style={styles.temp}>{weather.temp}°C</Text>
      <Text style={styles.condition}>{weather.condition}</Text>
      <Picker
        selectedValue={weather.city}
        onValueChange={(value) => setWeather(getWeather(value))}>
        <Picker.Item label='London' value='London' />
        <Picker.Item label='Manchester' value='Manchester' />
      </Picker>
    </View>
  );
}
const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  city: { fontSize: 24, marginBottom: 8 },
  temp: { fontSize: 64, fontWeight: 'bold' },
  condition: { fontSize: 18, color: '#555' }
});
export default App;

Practice Write the full app

Replace the outer View shell with a <ScrollView>. Give its refreshControl prop a <RefreshControl refreshing={'{refreshing}'} onRefresh={'{handleRefresh}'} />. Define refreshing with useState(false) and a handleRefresh that calls setRefreshing(false) after two seconds. Keep the card and Picker inside. Export the App function.

Starter code

App.js
import { useState } from 'react';
import { View, Text, StyleSheet, ScrollView, RefreshControl } from 'react-native';
import { Picker } from '@react-native-picker/picker';

const WEATHER_BY_CITY = {
  'London': { city: 'London', temp: 14, condition: 'Cloudy' },
  'Manchester': { city: 'Manchester', temp: 12, condition: 'Rainy' }
};
const getWeather = (city) => WEATHER_BY_CITY[city] || WEATHER_BY_CITY['London'];

function App() {
  const [weather, setWeather] = useState(getWeather('London'));
  // write refreshing state and handleRefresh here
  return (
    <View style={styles.container}>
      <Text style={styles.city}>{weather.city}</Text>
      <Text style={styles.temp}>{weather.temp}°C</Text>
      <Text style={styles.condition}>{weather.condition}</Text>
      <Picker selectedValue={weather.city} onValueChange={(value) => setWeather(getWeather(value))}>
        <Picker.Item label='London' value='London' />
        <Picker.Item label='Manchester' value='Manchester' />
      </Picker>
    </View>
  );
}
const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  city: { fontSize: 24, marginBottom: 8 },
  temp: { fontSize: 64, fontWeight: 'bold' },
  condition: { fontSize: 18, color: '#555' }
});
export default App;

Sample solution

App.js
import { useState } from 'react';
import { View, Text, StyleSheet, ScrollView, RefreshControl } from 'react-native';
import { Picker } from '@react-native-picker/picker';

const WEATHER_BY_CITY = {
  'London': { city: 'London', temp: 14, condition: 'Cloudy' },
  'Manchester': { city: 'Manchester', temp: 12, condition: 'Rainy' }
};
const getWeather = (city) => WEATHER_BY_CITY[city] || WEATHER_BY_CITY['London'];

function App() {
  const [weather, setWeather] = useState(getWeather('London'));
  const [refreshing, setRefreshing] = useState(false);
  const handleRefresh = () => {
    setRefreshing(true);
    setTimeout(() => setRefreshing(false), 2000);
  };
  return (
    <ScrollView style={styles.container} contentContainerStyle={{ alignItems: 'center', justifyContent: 'center', flex: 1 }} refreshControl={<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />}>
      <Text style={styles.city}>{weather.city}</Text>
      <Text style={styles.temp}>{weather.temp}°C</Text>
      <Text style={styles.condition}>{weather.condition}</Text>
      <Picker selectedValue={weather.city} onValueChange={(value) => setWeather(getWeather(value))}>
        <Picker.Item label='London' value='London' />
        <Picker.Item label='Manchester' value='Manchester' />
      </Picker>
    </ScrollView>
  );
}
const styles = StyleSheet.create({
  container: { flex: 1 },
  city: { fontSize: 24, marginBottom: 8 },
  temp: { fontSize: 64, fontWeight: 'bold' },
  condition: { fontSize: 18, color: '#555' }
});
export default App;

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 How do you do pull-to-refresh?

  • Only with Pressable
  • With RefreshControl Correct answer
  • Only with StyleSheet
  • Only with Picker

Explanation: RefreshControl works with refreshing and onRefresh.

2 Match the integration parts

Term Meaning
ScrollView Outer shell
RefreshControl Pull-to-refresh
Picker City selection
weather state Temperature and condition data

All lessons in Beginner