Part 4 of 5: React Coding Practice Problems

Jon Christie
8 min readFeb 24, 2023

--

Implementing a search feature in a React application & Building a real-time chat application with React and Firebase.

-Jon Christie

Implementing a search feature in a React application

typically involves setting up a search input field, capturing user input, and filtering a list of items based on the search term.

Here is an example of how to implement a search feature in React:

  1. Create a state for the search terms and search results:
import React, { useState } from 'react';

function Search() {
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState([]);

// Dummy data
const data = [
{ name: 'John', age: 20 },
{ name: 'Jane', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Alice', age: 35 },
];

// Function to handle search input changes
const handleSearch = (event) => {
setSearchTerm(event.target.value);
};

return (
<div>
<input type="text" value={searchTerm} onChange={handleSearch} />
{searchResults.map((item) => (
<div>{item.name} - {item.age}</div>
))}
</div>
);
}

export default Search;

2. Filter the data based on the search term:

import React, { useState } from 'react';

function Search() {
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState([]);

// Dummy data
const data = [
{ name: 'John', age: 20 },
{ name: 'Jane', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Alice', age: 35 },
];

// Function to handle search input changes
const handleSearch = (event) => {
setSearchTerm(event.target.value);
const results = data.filter((item) =>
item.name.toLowerCase().includes(searchTerm.toLowerCase())
);
setSearchResults(results);
};

return (
<div>
<input type="text" value={searchTerm} onChange={handleSearch} />
{searchResults.map((item) => (
<div>{item.name} - {item.age}</div>
))}
</div>
);
}

export default Search;
  1. Display the search results in the UI:
import React, { useState } from 'react';

function Search() {
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState([]);

// Dummy data
const data = [
{ name: 'John', age: 20 },
{ name: 'Jane', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Alice', age: 35 },
];

// Function to handle search input changes
const handleSearch = (event) => {
setSearchTerm(event.target.value);
const results = data.filter((item) =>
item.name.toLowerCase().includes(searchTerm.toLowerCase())
);
setSearchResults(results);
};

return (
<div>
<input type="text" value={searchTerm} onChange={handleSearch} />
{searchResults.length > 0 ? (
searchResults.map((item) => (
<div>{item.name} - {item.age}</div>
))
) : (
<div>No results found</div>
)}
</div>
);
}

export default Search;

This is a basic implementation of a search feature in React. You can customize it to fit your specific needs, such as adding more advanced search options, sorting the search results, or handling API requests.

If you want to use an external library to simplify the search feature implementation, you can use a library like React-Select or React-Search-Box.

React-Select is a flexible and easy-to-use select input control with advanced search and filtering capabilities. It supports keyboard navigation, accessibility, and can be styled to fit your app’s design.

React-Search-Box is a simple search box component with real-time search suggestions, fuzzy matching, and customizations for debounce delay, placeholder, and search icon. It is also easy to use and configure.

To use either of these libraries, you can install them via NPM and import them into your React component. Here’s an example of how to use React-Select:

import React, { useState } from 'react';
import Select from 'react-select';

function Search() {
const [selectedOption, setSelectedOption] = useState(null);

// Dummy data
const options = [
{ value: 'John', label: 'John' },
{ value: 'Jane', label: 'Jane' },
{ value: 'Bob', label: 'Bob' },
{ value: 'Alice', label: 'Alice' },
];

// Function to handle select option changes
const handleChange = (option) => {
setSelectedOption(option);
};

return (
<div>
<Select
value={selectedOption}
onChange={handleChange}
options={options}
isSearchable={true}
placeholder="Search..."
/>
</div>
);
}

export default Search;

This is just a basic example of how to use React-Select. You can customize the component further to fit your specific needs, such as styling it with CSS or providing additional props isMulti or menuPlacement.

In summary, implementing a search feature in React can be achieved by setting up a search input field, capturing user input, filtering a list of items based on the search term, and displaying the search results in the UI. You can use an external library like React-Select or React-Search-Box to simplify the implementation and add more advanced search options.

Build a real-time chat application with React and Firebase

Building a real-time chat application with React and Firebase can be done in a few steps:

  1. Set up a Firebase project and create a new Firebase app.
  2. Install Firebase dependencies and initialize Firebase in your React application:
npm install firebase
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/messaging';
import 'firebase/compat/firestore';
import 'firebase/compat/database';

const firebaseConfig = {
apiKey: "AIzaSyAUS18XUeQwRmeBI3lm7QTETXaN1G-IcxM",
authDomain: "react-interview-challenges.firebaseapp.com",
projectId: "react-interview-challenges",
storageBucket: "react-interview-challenges.appspot.com",
messagingSenderId: "27647234037",
appId: "1:27647234037:web:ece129ef7486651cbd9abc",
measurementId: "G-CNFE0KVC67"
};
firebase.initializeApp(firebaseConfig);

const database = firebase.database();

export { firebase, database };

3. Create a Chat component that displays the chat messages and allows users to send new messages:

import React, { useState, useEffect, useContext } from 'react';
import { database } from '../firebase/firebase';
import { FirebaseContext } from '../index';

function Chat() {
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState('');
const firebase = useContext(FirebaseContext);

// Get messages from Firebase Realtime Database on component mount
useEffect(() => {
const messagesRef = database.ref('messages');
messagesRef.on('value', (snapshot) => {
const messagesData = snapshot.val();
if (messagesData) {
const messages = Object.entries(messagesData).map(([key, value]) => {
return { id: key, ...value };
});
setMessages(messages);
}
});
}, []);

// Function to handle sending new message to Firebase Realtime Database
const handleSendMessage = (event) => {
event.preventDefault();
const messagesRef = database.ref('messages');
messagesRef.push({ text: newMessage, userId: firebase.auth().currentUser.uid, timestamp: Date.now() });
setNewMessage('');
};

return (
<div>
{messages.map((message) => (
<div key={message.id}>
{message.text} - {message.userId}
</div>
))}
<form onSubmit={handleSendMessage}>
<input type="text" value={newMessage} onChange={(e) => setNewMessage(e.target.value)} />
<button type="submit">Send</button>
</form>
</div>
);
}

export default Chat;

Your App.js will look like the following:

import React, { useState, useContext } from 'react';
import { firebase } from './firebase/firebase';
import { FirebaseContext } from './index';
import Chat from './components/Chat';

function App() {
const [user, setUser] = useState(null);
const firebaseInstance = useContext(FirebaseContext);

// Function to handle signing in with Google account
const handleSignIn = () => {
const provider = new firebaseInstance.auth.GoogleAuthProvider();
firebaseInstance.auth().signInWithPopup(provider);
};

// Function to handle signing out
const handleSignOut = () => {
firebaseInstance.auth().signOut();
};

// Listen for changes in user authentication state
firebaseInstance.auth().onAuthStateChanged((user) => {
setUser(user);
});

return (
<div>
{user ? (
<div>
<h1>Welcome, {user.displayName}!</h1>
<button onClick={handleSignOut}>Sign Out</button>
<Chat />
</div>
) : (
<div>
<h1>Please sign in to continue.</h1>
<button onClick={handleSignIn}>Sign In with Google</button>
</div>
)}
</div>
);
}

export default App;

In this file, we start by importing the necessary modules for the component to work, including the React module, as well as the useState and useContext hooks from the react library.

import React, { useState, useContext } from 'react';

Next, we import the firebase module from a local firebase.js file, the FirebaseContext object from the index.js file in the root directory, and the Chat component from a local Chat.js file.

import { firebase } from './firebase/firebase';
import { FirebaseContext } from './index';
import Chat from './components/Chat';

This line defines a functional component called App.

function App() {

This line initializes a state variable called user to null using the useState hook. It also defines a function called setUser that can be used to update the user state variable.

 const [user, setUser] = useState(null);

This line initializes a variable called firebaseInstance using the useContext hook. It retrieves the FirebaseContext object, which is used to access the Firebase instance in the application.

const firebaseInstance = useContext(FirebaseContext);

This defines a function called handleSignIn that is used to sign the user in with their Google account. It first creates an instance of the GoogleAuthProvider using the firebaseInstance object, and then uses the signInWithPopup method to sign the user in using that provider.

const handleSignIn = () => { 
const provider = new firebaseInstance.auth.GoogleAuthProvider();
firebaseInstance.auth().signInWithPopup(provider); };

This defines a function called handleSignOut that is used to sign the user out of the application. It uses the signOut method provided by the firebaseInstance object.

const handleSignOut = () => {
firebaseInstance.auth().signOut();
};

This sets up a listener that watches for changes in the user authentication state, and updates the user state variable accordingly.

firebaseInstance.auth().onAuthStateChanged((user) => {
setUser(user);
});

Finally, this returns the JSX that will be rendered to the screen. The return statement includes a ternary operator that checks whether the user state variable is null or not, and renders the appropriate JSX accordingly. If the user is signed in, it displays a welcome message, a sign out button, and the Chat component. If the user is not signed in, it displays a message prompting the user to sign in and a button to trigger the handleSignIn function.

 return (
<div>
{user ? (
<div>
<h1>Welcome, {user.displayName}!</h1>
<button onClick={handleSignOut}>Sign Out</button>
<Chat />
</div>
) : (
<div>
<h1>Please sign in to continue.</h1>
<button onClick={handleSignIn}>Sign In with Google</button>
</div>
)}
</div>
);

This line exports the App component to be used in other parts of the application.

export default App;

This is a simple example of how to build a real-time chat application with React and Firebase. You can customize the chat component further to add more advanced features like user authentication, chat rooms, or message editing and deletion. You can also explore other Firebase services like Cloud Firestore, Firebase Authentication, or Firebase Hosting to build a more complete chat application.

Additional Setup

Here are some links and instructions on how to obtain the necessary keys for Firebase:

  1. Go to the Firebase console and create a new Firebase project: https://console.firebase.google.com/
  2. Add a new web app to your Firebase project and register it with your app’s package name and SHA-1 fingerprint: https://firebase.google.com/docs/web/setup#register-app
  3. In your web app’s dashboard, go to the “Project settings” and find the “Firebase SDK snippet” section. Select “Config” and copy the Firebase configuration object that contains the following keys:
  • apiKey
  • authDomain
  • databaseURL
  • projectId
  • storageBucket
  • messagingSenderId
  • appId
  1. Paste the Firebase configuration object in your React app’s initialization code, as shown in the previous example.
  2. Enable the Firebase Realtime Database in your Firebase project and configure its security rules: https://firebase.google.com/docs/database
  3. To secure your Firebase project, you can set up Firebase Authentication to require users to sign in before they can access the chat application: https://firebase.google.com/docs/auth
  4. To deploy your React app and Firebase project, you can use Firebase Hosting and the Firebase CLI: https://firebase.google.com/docs/hosting https://firebase.google.com/docs/cli

Note that Firebase provides a generous free tier for usage of its services, but usage beyond this may require payment. You can find more information about Firebase pricing here: https://firebase.google.com/pricing.

Additionally, here are some more resources that you can use to learn more about building a real-time chat application with React and Firebase:

  1. Firebase documentation on building a chat app with Firebase Realtime Database: https://firebase.google.com/docs/database/web/start
  2. Firebase documentation on integrating Firebase with React: https://firebase.google.com/docs/web/setup
  3. Firebase documentation on securing your Firebase project with Firebase Authentication: https://firebase.google.com/docs/auth/web/start
  4. A tutorial on building a real-time chat application with React and Firebase on FreeCodeCamp: https://www.freecodecamp.org/news/how-to-build-a-real-time-chat-app-with-react-and-firebase/
  5. A video tutorial on building a real-time chat application with React and Firebase on YouTube: https://www.youtube.com/watch?v=zQyrwxMPm88

I hope these resources are helpful for you in building your real-time chat application with React and Firebase. Good luck with your journey!

--

--

Jon Christie

Web Developer | UI/UX Designer | Graphic Artist | Educator | Musician | Technical Writer