Open In App

Build a Dictionary App Using React Native

Last Updated : 01 Jun, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

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.

Build-a--Dictionary--App-Using

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, che­ckedWord, 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 corre­sponding 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>


- SearchBar and Button:

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>)}


- Clear Button:

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:


Next Article
Article Tags :

Similar Reads