Build a Dictionary App Using React Native
Last Updated :
23 Jul, 2025
In this article, we will implement a Dictionary app using React Native. The app allows users to effortlessly search for word meanings, access definitions, listen to pronunciations, and examine example sentences.
To give you a better idea of what we’re going to create, let’s watch a demo video.
Demo Video
Playground
Note: This Section is to interact with the app which you are going to build.
Prerequisites
Step-by-Step Implementation
Step 1: Create a React Native Project
Now, create a project with the following command.
npx create-expo-app app-name --template
Note: Replace the app-name with your app name for example : react-native-demo-app
Next, you might be asked to choose a template. Select one based on your preference as shown in the image below. I am selecting the blank template because it will generate a minimal app that is as clean as an empty canvas in JavaScript.
It completes the project creation and displays a message: "Your Project is ready!" as shown in the image below.
Now go into your project folder, i.e., react-native-demo
cd app-name
Project Structure:
Step 2: Run Application
Start the server by using the following command.
npx expo start
Then, the application will display a QR code.
- For the Android users,
- For the Android Emulator, press " a" as mentioned in the image below.
- For the Physical Device, download the " Expo Go " app from the Play Store. Open the app, and you will see a button labeled " Scan QR Code. " Click that button and scan the QR code; it will automatically build the Android app on your device.
- For iOS users, simply scan the QR code using the Camera app .
- If you're using a web browser, it will provide a local host link that you can use as mentioned in the image below.
Step 3: Install the required Library
Now, run the below command to install the expo-av library, which is used to access the audio.
npm install expo-av
Step 4: Start Coding
- Approach:
- The useState hook is used to declare and initialize state variables efficiently. These variables, including newWord, checkedWord, definition, example, sound, and data, play crucial roles in storing different pieces of information throughout the app's
- This function is invoked when the user inputs a word into the search field. It then updates the new word state with the entered word.
- The getInfo function is triggered when the user clicks the "Search" button. It performs data retrieval from a dictionary API based on the entered word. After retrieving the response, it processes the data and updates the state with comprehensive information about the word, including its definition and an example of its usage.
- This function enables the user to easily listen to the accurate pronunciation of a word. By checking the availability of audio data, it utilizes the eXPO-AV library to seamlessly load and play the corresponding audio.
- The clear function serves to reset the application's state variables and unload any previously loaded audio. Furthermore, it effectively removes the results from the previous search, allowing users to initiate a fresh search with ease.
Let's dive into the code in detail.
- Import libraries:
Import required libraries at the top of the file.
JavaScript
// Import necessary hooks and components from React and React Native
import { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, ScrollView }
from 'react-native';
// Import Audio module from expo-av for playing audio
import { Audio } from 'expo-av';
// Import AntDesign icon set from react-native-vector-icons
import { AntDesign }
from 'react-native-vector-icons';
// Import custom styles
import styles from './styles';
- StyleSheet:
Create a StyleSheet file, name it as Styles.js to style components like container, errorText, heading, etc.
JavaScript
// Styles.js
// Define a styles object containing all style definitions
const styles = {
// Container for the main layout
container: {
flex: 1, // Take up the full available space
alignItems: 'center', // Center items horizontally
backgroundColor: '#F5F5F5', // Light gray background color
padding: 20, // Padding around the container
},
// Style for error text messages
errorText: {
color: 'red', // Red text color
fontSize: 23, // Large font size
marginTop: 10, // Margin at the top
},
// Style for headings
heading: {
fontSize: 30, // Large font size
marginBottom: 20, // Margin below the heading
fontWeight: 'bold', // Bold text
color: '#333', // Dark gray text color
},
// Container for input fields
inputContainer: {
flexDirection: 'row', // Arrange children in a row
alignItems: 'center', // Center items vertically
marginBottom: 20, // Margin below the container
backgroundColor: '#FFF', // White background
borderRadius: 10, // Rounded corners
shadowColor: 'grey', // Shadow color
shadowOffset: { width: 0, height: 2 }, // Shadow offset
shadowOpacity: 0.2, // Shadow opacity
shadowRadius: 3, // Shadow blur radius
elevation: 3, // Android shadow elevation
},
// Style for text input fields
input: {
flex: 1, // Take up remaining space in the row
padding: 15, // Padding inside the input
fontSize: 18, // Font size
},
// Style for buttons
button: {
backgroundColor: '#007BFF', // Blue background color
padding: 15, // Padding inside the button
marginLeft: 10, // Margin to the left
borderRadius: 10, // Rounded corners
},
// Style for button text
buttonText: {
color: '#fff', // White text color
fontWeight: 'bold', // Bold text
fontSize: 18, // Font size
},
// Container for displaying results
resultsContainer: {
backgroundColor: '#FFF', // White background
borderRadius: 10, // Rounded corners
shadowColor: '#000', // Shadow color
shadowOffset: { width: 0, height: 2 }, // Shadow offset
shadowOpacity: 0.2, // Shadow opacity
shadowRadius: 3, // Shadow blur radius
elevation: 3, // Android shadow elevation
padding: 20, // Padding inside the container
height: 300, // Fixed height
},
// Style for displaying a word
word: {
fontSize: 24, // Large font size
fontWeight: 'bold', // Bold text
marginBottom: 10, // Margin below the word
},
// Style for the play button
playButton: {
backgroundColor: '#2ecc71', // Green background color
width: 60, // Button width
height: 60, // Button height
borderRadius: 30, // Circular button
alignItems: 'center', // Center content horizontally
justifyContent: 'center', // Center content vertically
marginTop: 20, // Margin at the top
},
// Style for play button text/icon
playButtonText: {
color: '#fff', // White text color
fontSize: 20, // Font size
fontWeight: 'bold', // Bold text
},
// Container for result text
resultTextContainer: {
alignItems: 'center', // Center items horizontally
paddingTop: 20, // Padding at the top
},
// Style for result text
resultText: {
fontSize: 18, // Font size
marginBottom: 10, // Margin below the text
},
// Style for the clear button
clearButton: {
backgroundColor: '#FF4A4A', // Red background color
padding: 15, // Padding inside the button
marginTop: 20, // Margin at the top
borderRadius: 10, // Rounded corners
},
// Style for clear button text
clearButtonText: {
color: '#fff', // White text color
fontWeight: 'bold', // Bold text
fontSize: 18, // Font size
},
};
// Export the styles object for use in other files
export default styles;
- Title Text:
This title explains what the app does. We use the text "Dictionary App" to show that the app is a Dictionary App.
JavaScript
{/* Title-Text */}
<Text style={styles.heading}>Dictionary App</Text>
In the below code, we have a TextInput component to take input from user and search button used to call getInfo function designed using TouchableOpactiy component, which will execute the logic of fetching the meaning and example for user input. These two components are wrapped with View Component to hold them together.
When the user entering any text or modifying the text inside the TextInput component it will send that input text to searchWord function using onChangeText prop in TextInput component, which will assign that text to newWord state variable by calling setNewWord state function with enteredWord and that newWord state variable further used in fetching the meaning and example process.
JavaScript
// State to store the word entered by the user
const [newWord, setNewWord] = useState("");
// Function to update the newWord state as the user types
const searchWord = (enteredWord) => {
setNewWord(enteredWord)
};
{/* Input field and search button */}
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Search..."
onChangeText={(text) => searchWord(text)} />
<TouchableOpacity style={styles.button}
onPress={() => getInfo()}>
<Text style={styles.buttonText}>Search</Text>
</TouchableOpacity>
</View>
- getInfo function:
This function is used to make a GET request by appending the user input text, i.e, word to URL given in below code and set all states for that word like checkedWord, definition, example, error (optional) etc.
JavaScript
// State to store the word that was checked/searched
const [checkedWord, setCheckedWord] = useState("");
// State to store the definition of the word
const [definition, setDefinition] = useState("");
// State to store an example usage of the word
const [example, setExample] = useState("");
// State to store the audio sound object
const [sound, setSound] = useState();
// State to store the fetched data from the API
const [data, setData] = useState(null);
// State to store any error messages
const [error, setError] = useState(null);
// Function to fetch word information from the dictionary API
const getInfo = async () => {
// Construct the API URL using the entered word
let url = "https://api.dictionaryapi.dev/api/v2/entries/en/" + newWord;
try {
// Fetch data from the API
const response = await fetch(url);
const fetchedData = await response.json();
if (response.status === 200) {
// If the response is successful, update the data state
setData(fetchedData);
// Extract and set the checked word
let word = fetchedData[0].word;
setCheckedWord(word);
// Extract and set the definition
let def = fetchedData[0]
.meanings[0].definitions[0].definition;
setDefinition(def);
// Extract and set the example usage
let eg = fetchedData[0]
.meanings[0].definitions[0].example;
setExample(eg);
// Clear any previous error
setError(null);
}
else {
// If the API returns an error, set the error state
setError("Word not found in the database");
// Automatically clear the error after 3 seconds
setTimeout(() => {
setError(null);
}, 3000);
}
}
catch (error) {
// Handle any network or fetch errors
console.error('Error fetching data:', error);
setError("An error occurred while fetching data");
// Automatically clear the error after 3 seconds
setTimeout(() => { setError(null); }, 3000);
}
};
- Error Text:
Display the Error text using the code below when the request or response is stuck with any error.
JavaScript
// State to store any error messages
const [error, setError] = useState(null);
{/* Display error message if any */}
{error && (
<Text style={styles.errorText}>{error}</Text>)}
- Display Result:
Display the meaning and example of the user input word when the response is successful using the code below.
The Below code consists of a Text component to display the word what user submitted, a Icon button to call playAudio function which will enable audio to read that word out and a Text component wrapped with View component with some styling for displaying Definition and example of that word, also wrap all these components with a ScrollView component to hold all component together and enable the scrollability.
JavaScript
{/* Display results if a word has been checked and there is no error */}
{checkedWord && !error && (
<ScrollView style={styles.resultsContainer}>
<Text style={styles.word}>{checkedWord}</Text>
{/* Button to play pronunciation audio */}
<TouchableOpacity style={styles.playButton}
onPress={() => playAudio()}>
<AntDesign name="sound" size={20} color="#ffffff" />
</TouchableOpacity>
{/* Display definition and example */}
<View style={styles.resultTextContainer}>
<Text style={styles.resultText}>
Definition: {definition}
</Text>
<Text style={styles.resultText}>
Example: {example}
</Text>
</View>
</ScrollView>)}
This button is used to call a clear function, which clears the result UI and TextInput field, redefines the UI to write a new word again. It is designed using a Text component having some text like "Clear" wrapping with a TouchableOpacity component.
JavaScript
{/* Button to clear all fields */}
<TouchableOpacity style={styles.clearButton}
onPress={() => clear()}>
<Text style={styles.buttonText}>Clear</Text>
</TouchableOpacity>
- clear function:
As we discussed in the clear Button, This function is used to clear the result UI and TextInput field, redefines the UI to write a new word again.
JavaScript
// Function to clear all states and unload any audio
const clear = async () => {
setCheckedWord("");
setDefinition("");
setExample("");
setNewWord("");
// Unload the audio if it exists
if (sound) {
await sound.unloadAsync()
}
};
Now, wrap all design code with a View component, return it from the App component, and place all methods and useStates within the App component. Ensure to export the App.
Complete Source Code
App.js
// Import necessary hooks and components from React and React Native
import { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, ScrollView }
from 'react-native';
// Import Audio module from expo-av for playing audio
import { Audio } from 'expo-av';
// Import AntDesign icon set from react-native-vector-icons
import { AntDesign }
from 'react-native-vector-icons';
// Import custom styles
import styles from './styles';
// Main App component
export default function App() {
// State to store the word entered by the user
const [newWord, setNewWord] = useState("");
// State to store the word that was checked/searched
const [checkedWord, setCheckedWord] = useState("");
// State to store the definition of the word
const [definition, setDefinition] = useState("");
// State to store an example usage of the word
const [example, setExample] = useState("");
// State to store the audio sound object
const [sound, setSound] = useState();
// State to store the fetched data from the API
const [data, setData] = useState(null);
// State to store any error messages
const [error, setError] = useState(null);
// Function to update the newWord state as the user types
const searchWord = (enteredWord) => {
setNewWord(enteredWord)
};
// Function to fetch word information from the dictionary API
const getInfo = async () => {
// Construct the API URL using the entered word
let url =
"https://api.dictionaryapi.dev/api/v2/entries/en/" + newWord;
try {
// Fetch data from the API
const response = await fetch(url);
const fetchedData = await response.json();
if (response.status === 200) {
// If the response is successful, update the data state
setData(fetchedData);
// Extract and set the checked word
let word = fetchedData[0].word;
setCheckedWord(word);
// Extract and set the definition
let def = fetchedData[0]
.meanings[0].definitions[0].definition;
setDefinition(def);
// Extract and set the example usage
let eg = fetchedData[0]
.meanings[0].definitions[0].example;
setExample(eg);
// Clear any previous error
setError(null);
}
else {
// If the API returns an error, set the error state
setError("Word not found in the database");
// Automatically clear the error after 3 seconds
setTimeout(() => {
setError(null);
}, 3000);
}
}
catch (error) {
// Handle any network or fetch errors
console.error('Error fetching data:', error);
setError("An error occurred while fetching data");
// Automatically clear the error after 3 seconds
setTimeout(() => { setError(null); }, 3000);
}
};
// Function to play the pronunciation audio of the word
const playAudio = async () => {
// Check if audio data is available
if (data && data[0].phonetics && data[0].phonetics[0]
&& data[0].phonetics[0].audio) {
// Unload any previously loaded sound
if (sound) {
await sound.unloadAsync()
}
// Get the audio URI from the API data
const audioUri = data[0].phonetics[0].audio;
// Load the audio file
const { sound, status } =
await Audio.Sound.createAsync({ uri: audioUri });
// If the audio is loaded, play it and update the sound state
if (status.isLoaded) {
setSound(sound);
await sound.playAsync()
}
}
};
// Function to clear all states and unload any audio
const clear = async () => {
setCheckedWord("");
setDefinition("");
setExample("");
setNewWord("");
// Unload the audio if it exists
if (sound) {
await sound.unloadAsync()
}
};
// Render the UI
return (
<View style={styles.container}>
{/* App heading */}
<Text style={styles.heading}>Dictionary App</Text>
{/* Input field and search button */}
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Search..."
onChangeText={(text) => searchWord(text)} />
<TouchableOpacity style={styles.button}
onPress={() => getInfo()}>
<Text style={styles.buttonText}>Search</Text>
</TouchableOpacity>
</View>
{/* Display error message if any */}
{error && (
<Text style={styles.errorText}>{error}</Text>)}
{/* Display results if a word has been checked and there is no error */}
{checkedWord && !error && (
<ScrollView style={styles.resultsContainer}>
<Text style={styles.word}>{checkedWord}</Text>
{/* Button to play pronunciation audio */}
<TouchableOpacity style={styles.playButton}
onPress={() => playAudio()}>
<AntDesign name="sound" size={20} color="#ffffff" />
</TouchableOpacity>
{/* Display definition and example */}
<View style={styles.resultTextContainer}>
<Text style={styles.resultText}>
Definition: {definition}
</Text>
<Text style={styles.resultText}>
Example: {example}
</Text>
</View>
</ScrollView>)}
{/* Button to clear all fields */}
<TouchableOpacity style={styles.clearButton}
onPress={() => clear()}>
<Text style={styles.buttonText}>Clear</Text>
</TouchableOpacity>
</View>
);
}
styles.js
// Styles.js
// Define a styles object containing all style definitions
const styles = {
// Container for the main layout
container: {
flex: 1, // Take up the full available space
alignItems: 'center', // Center items horizontally
backgroundColor: '#F5F5F5', // Light gray background color
padding: 20, // Padding around the container
},
// Style for error text messages
errorText: {
color: 'red', // Red text color
fontSize: 23, // Large font size
marginTop: 10, // Margin at the top
},
// Style for headings
heading: {
fontSize: 30, // Large font size
marginBottom: 20, // Margin below the heading
fontWeight: 'bold', // Bold text
color: '#333', // Dark gray text color
},
// Container for input fields
inputContainer: {
flexDirection: 'row', // Arrange children in a row
alignItems: 'center', // Center items vertically
marginBottom: 20, // Margin below the container
backgroundColor: '#FFF', // White background
borderRadius: 10, // Rounded corners
shadowColor: 'grey', // Shadow color
shadowOffset: { width: 0, height: 2 }, // Shadow offset
shadowOpacity: 0.2, // Shadow opacity
shadowRadius: 3, // Shadow blur radius
elevation: 3, // Android shadow elevation
},
// Style for text input fields
input: {
flex: 1, // Take up remaining space in the row
padding: 15, // Padding inside the input
fontSize: 18, // Font size
},
// Style for buttons
button: {
backgroundColor: '#007BFF', // Blue background color
padding: 15, // Padding inside the button
marginLeft: 10, // Margin to the left
borderRadius: 10, // Rounded corners
},
// Style for button text
buttonText: {
color: '#fff', // White text color
fontWeight: 'bold', // Bold text
fontSize: 18, // Font size
},
// Container for displaying results
resultsContainer: {
backgroundColor: '#FFF', // White background
borderRadius: 10, // Rounded corners
shadowColor: '#000', // Shadow color
shadowOffset: { width: 0, height: 2 }, // Shadow offset
shadowOpacity: 0.2, // Shadow opacity
shadowRadius: 3, // Shadow blur radius
elevation: 3, // Android shadow elevation
padding: 20, // Padding inside the container
height: 300, // Fixed height
},
// Style for displaying a word
word: {
fontSize: 24, // Large font size
fontWeight: 'bold', // Bold text
marginBottom: 10, // Margin below the word
},
// Style for the play button
playButton: {
backgroundColor: '#2ecc71', // Green background color
width: 60, // Button width
height: 60, // Button height
borderRadius: 30, // Circular button
alignItems: 'center', // Center content horizontally
justifyContent: 'center', // Center content vertically
marginTop: 20, // Margin at the top
},
// Style for play button text/icon
playButtonText: {
color: '#fff', // White text color
fontSize: 20, // Font size
fontWeight: 'bold', // Bold text
},
// Container for result text
resultTextContainer: {
alignItems: 'center', // Center items horizontally
paddingTop: 20, // Padding at the top
},
// Style for result text
resultText: {
fontSize: 18, // Font size
marginBottom: 10, // Margin below the text
},
// Style for the clear button
clearButton: {
backgroundColor: '#FF4A4A', // Red background color
padding: 15, // Padding inside the button
marginTop: 20, // Margin at the top
borderRadius: 10, // Rounded corners
},
// Style for clear button text
clearButtonText: {
color: '#fff', // White text color
fontWeight: 'bold', // Bold text
fontSize: 18, // Font size
},
};
// Export the styles object for use in other files
export default styles;
Output: