How to make a dynamic background for React Native apps loading from API
There are tons of cool APIs where we can get images from for our apps. In this guide we are going to use Pixabay API for loading background images. You will need to get an API key from pixabay.com.
Import ImageBackground
element from react-native
import { ImageBackground} from 'react-native';
Add ImageBackground as the parent element in your component where you want to apply it and add styles:
export default function SomeComponent(props) {
return (
// rendering ImageBackground element with backgroundImage from state passed as source of the image
<ImageBackground
source={{ uri: backgroundImage }}
style={styles.background}
>
<View style={styles.app}>
</View>
</ImageBackground>
);
}
Styles:
const styles = StyleSheet.create({
background: {
flex: 1,
resizeMode: "cover",
justifyContent: "flex-end"
},
app: {
marginHorizontal: "auto",
maxWidth: 500,
backGroundColor: "transparent"
}
});
Import useState
and declare state variable for the image with some default image:
import {useState} from 'react'// declare state variable for single background image, initially some image
const [backgroundImage, setBackgroundImage] = useState("https://pixabay.com/get/g5087a1cec28279208368920fd3d30343bf08ca1002b5316e4cdd8fac66e19af31811080dc13c67f0f49c113298c4724166f201a96b48651d0b49efddfea5d2b6_640.jpg");
Add a function to fetch the images from some API, for example from Pixabay:
// Please add your api key which you can get from pixabay.com
const pixabayAPIkey='YOUR API KEY'
let newBackground = () => {
// sending request to the API
fetch(
`https://pixabay.com/api/?key=${pixabayAPIkey}&q=cat&orientation=vertical&safesearch=true&per_page=100`
)
.then((data) => {
return data.json();
})
.then((pics) => {
// creating a random number for index to pick one of the images from 100 we will get
let randomImage = parseInt(Math.random() * pics.totalHits);
// set this random image to tbe the current background
setBackgroundImage(pics.hits[randomImage].largeImageURL);
// set all images in state to use later for changing the background
setAllImages(pics.hits);
})
.catch((err) => {
console.log(err);
})
.finally(() => console.log("Finally: ", backgroundImage, allImages.length));
};
// executing the function only on first load once, no need for useEffect
newBackground();
In this function we will get an array of images, so let’s save them in state and then use to update backgrounds instead of sending a new request every time during the lifecycle of component and abuse API.
We will add a state variable to keep all those images:
// declare state variable for all images we will get from API
const [allImages, setAllImages] = useState([]);
it will be updated from the newBackground
with setAllImages(pics.hits)
Now on first render we will get a bunch of images and set one of them to be the current background.
We can also add a button to change the background manually just to check. You can replace the button by some event created by user or your app to do it.
<Button title="New Kitty" onPress={()=>allImages.length>0&&updateBackground()} />
So the final code looks like that:
import React from "react";
// import all the elements we will use from react-native
import { ImageBackground, Button, StyleSheet, View } from "react-native";
// import useState
import { useState } from "react";function App() {
// declare state variable for single background image, initially some image
const [backgroundImage, setBackgroundImage] = useState("https://pixabay.com/get/g5087a1cec28279208368920fd3d30343bf08ca1002b5316e4cdd8fac66e19af31811080dc13c67f0f49c113298c4724166f201a96b48651d0b49efddfea5d2b6_640.jpg");
// declare state variable for all images we will get from API
const [allImages, setAllImages] = useState([]);
// Please add your api key which you can get from pixabay.com
const pixabayAPIkey='YOUR API KEY'
let newBackground = () => {
// sending request to the API
fetch(
`https://pixabay.com/api/?key=${pixabayAPIkey}&q=cat&orientation=vertical&safesearch=true&per_page=100`
)
.then((data) => {
return data.json();
})
.then((pics) => {
// creating a random number for index to pick one of the images from 100 we will get
let randomImage = parseInt(Math.random() * pics.totalHits);
// set this random image to tbe the current background
setBackgroundImage(pics.hits[randomImage].largeImageURL);
// set all images in state to use later for changing the background
setAllImages(pics.hits);
})
.catch((err) => {
console.log(err);
})
.finally(() => console.log("Finally: ", backgroundImage, allImages.length));
};
// executing the function only on first load once, no need for useEffect
newBackground(); // updating background from state
const updateBackground = () => {
// generating random index
let randomImage = parseInt(Math.random() * (allImages.length - 1));
// setting random image from images array in state to be the current background
setBackgroundImage(allImages[randomImage].largeImageURL);
}; return (
// rendering ImageBackground element with backgroundImage from state passed as source of the image
<ImageBackground
source={{ uri: backgroundImage }}
style={styles.background}
>
<View style={styles.app}>
{/* button to trigger change of the background if we have images in the allImages */}
<Button title="New Kitty" onPress={()=>allImages.length>0&&updateBackground()} />
</View>
</ImageBackground>
);
}const styles = StyleSheet.create({
background: {
flex: 1,
resizeMode: "cover",
justifyContent: "flex-end"
},
app: {
marginHorizontal: "auto",
maxWidth: 500,
backGroundColor: "transparent"
}
});export default App;
Here is the sandbox with code.
That’s it :)