How to Build React Components You Can Reuse
Take a look at this tutorial that demonstrates how to create a fully functional React component, pass and emit values, and connect it to Firebase.
Join the DZone community and get the full member experience.Join For Free
React lets you create a component for rating that can be used over and over, anyplace a rating component is needed. It’s even possible to add it to your company’s internal package management system, so that the component is easily consumed by any React application that needs it. Today, we’re going to be creating a beer rating app—Brewstr—using reusable react components.
You will need:
- A basic, working knowledge of React
- A free-forever Okta Developer Account
- A Firebase Real-Time Database
The create-react-app command-line tool
Scaffold Your React Application
To get this thing kicked off, scaffold a basic React application by running the following command in the terminal in a folder where you’d like to store your code:
Once this program has created your React application’s skeleton, change into your code directory and open it in your favorite code editor. I’ll be using Visual Studio Code, so I’ll run the following command:
Add Okta Authentication to Your React Application
Now that you have a basic React app, you’ll need to set up Okta to allow users to authenticate into your application. If you don’t already have one, create a free-forever Okta developer account. Once you’ve logged in, take note of your Okta org URL on the top right of the dashboard. Then choose Applications from the main menu and click Add Application.
In the wizard, choose Single-Page App from the available platforms and click Next. In the Application Settings page you’ll want to name the app “Brewstr” and change the BaseURIs, and Login redirect URIs values to use port 3000, and click Done. Take note of the Client ID for your newly created app.
Back in the React application, add two packages to your application:
.env.local file at the root of the project and add the following to it:
Then, in the
index.js file, add the following snippet right below the
Add some imports to your
Then replace the entire
ReactDOM.render statement with the following:
This sets up Okta to handle user authentication. It also makes it easy to get information about the logged in user by wrapping the
App component in the
Security component. Now you just have to use it.
To start simple, just change the
App.js file to look like this:
Make sure you’ve logged out of your Okta account, and then run the application with:
When you click on the Rate menu item, it should redirect you to log in with Okta. You can use the credentials you use to log in to your Okta dashboard. If you don’t get prompted to log in, it may be because the application still has you logged in. Go to your Okta dashboard and log out, then clear your tokens in the dev tools under Application, LocalStorage, http://localhost:3000. Then try to go to the Rate page again and make sure it prompts you to log in.
NOTE: If you’re still having problems getting the login to work, go back and double-check all your values and code from the previous steps.
Set Up a Firebase Real-Time Datastore
You’ll be storing your app’s beer ratings in a Firebase Real-Time Data Store, so you’ll need an account there. Once you’ve signed up and logged in, click the Add Project tile and choose the name “Brewstr,” then click Continue. On the next screen, turn off analytics (since it’s a test project), then click Create Project. This may take a few moments to get created. Once you see, “Your new project is ready,” click Continue.
You will then be taken to a screen that has three white icons for “Getting Started.” Choose the icon for web apps that should have
</> as the text. You’ll need to register the project you just created with Firebase, so put in the name of your app again, “Brewstr," and click Continue. You’ll see a chunk of code there, just copy it to an empty text file for now.
Now click Database in the left-hand menu and scroll down to Or choose Realtime Database. In that block, click on Create database and in the dialog that pops up choose Start in test mode then click Enable. The permissions here are completely open for reads and writes. Obviously, this is not the way you’ll want to set it up for production, but in the case of testing, this is the easiest set up.
Back in the editor, add some new keys to the
firebase package to your app:
firebase.js in your
This will set up the connection to the data store and allow you to use it wherever you need.
NOTE: You may need to stop the application from running (with a
CTRL+c) and restart it so it can pick up the environment variables you put in
Create a Star Rating Component
The beauty of React is being able to reuse common components and compose pages from those components. Since you’re creating a beer rating site, you’ll create a star rating component that will handle collecting users’ ratings.
Start by creating a folder called
components in the
src directory and add a
rater folder inside that. Then add two files:
star-rating.css. In the
star-rating.jsx file add the following contents:
import statements should be self-explanatory. The class component starts by setting up the basic state with a
prop passed in that allows parent components to set an initial rating. In the
componentDidMount() function the
this.setRating() function is called so the initial rating is reflected in the number of stars highlighted when the component loads.
The next three functions are handlers for the rating component. The
hoverHandler() function gets all the star elements in the components and as the user hovers and highlights all the stars up to (and including) the star being hovered over.
setRating() function is called from
componentDidMount() to highlight the stars with the initial rating. It is also called as an event handler from the component when the user moves their mouse away from the rating component without choosing a rating. This will reset the highlighting back to the current rating.
starClickHandler() is used by the component when a user clicks a rating. It sets the state’s
currentRating value so that the highlighting is locked in when the user moves their mouse away from the component. It also emits an event up to the parent’s
onClick handler that was passed to the component and passes up the rating that the user clicked on.
render() method displays a container to hold the stars and then it displays the requested number of stars, using a property passed in from the parent component. it loops through an array with that number of elements and gives each star a value of the current index + 1 to account for the zero-based nature of arrays. The relevant portion is:
This just uses the spread operator
... on a new array with a size based on the number of stars requested. Each star gets wired to the
starClickHandler() event handlers. The
★ is just the Unicode value of a star. I also added a little style to my stars in the
This just sets the initial color of the stars to gray. You don’t have to do this, but I think it makes it look a lot nicer and it can help if you’re putting the star rater component on a weird colored background.
Consume the Rating Component
Now that you’ve got a rating component, you’ll want to put it on a page. Create a folder in
pages and inside that add a new
rating folder with a
The contents of the
rating-page.jsx should be:
import statements bring in the
withAuth higher-order component from the
@okta/okta-react package. This allows you to get the currently logged in user when saving ratings for that user. This also brings in the Firebase set up and the
At the bottom of the file, you wrap the
RatingPage component with the
withAuth higher-order component. This allows you to get the currently logged in user in the
componentDidMount() function and add the user’s email address to the state. This will be saved with their ratings so that when they go to the
RatingList page, they will only see their ratings.
handleChange() function handles the changing of the text values for the beer name and description in the component’s form. The
setRating() handler is what is passed to the rating component so that when a user clicks on a rating, the value is propagated back to the parent and, in this case, is added to the state.
saveRating() function gets the reference to the Firebase store and pushes a new rating into the collection then the application is routed to the
render() method is pretty standard except where you add the
StarRating component. You set the
numberOfStars to five for this rating system, then set the
currentRating to zero. You could set it to two or three if you think that looks better. Finally, the reference to the click handler is passed to the
StarRating component, so that when a user chooses a rating, the value is bubbled back up to the click handler on this page component.
The stylesheet for this page is unremarkable. It just contains some styles to make it more readable.
Again, you’re bringing in the Okta and Firebase
componentDidMount() is getting the currently logged in user and passing it to Firebase to get a list of the ratings that this user has entered. All queries to Firebase return a “snapshot” represented here by the variable
snap and it is pushed onto an array and then the state is set with that array. If you push each “record” onto the array in the state object, the component will redraw each time one is pushed. That’s the reason you push onto another array and then only update the state once. The
render() function merely lists the ratings in a table.
Add Routing to the Actual Components
If you remember, all the routing is going to “fake” components that just spit out text right now. You’ll need to go back to the
App.js file and make sure the routes are hooked to the components you just created, so that the final file contents are:
Here, you just added the
imports for the component pages you just created, then updated or added routes to those components.
I also added some styling to my menu in
App.css in the
Rate Some Beers
Now when you run your application, you will be able to go to the Rate menu item and add a beer and a rating. If you’re not logged in, it will prompt you to do so. When you’ve entered a beer and rating, you’ll be routed to the listing page with a listing of all the beers you’ve rated.
So what does this all mean? What have you learned? You learned how to create a React component with all the functionality encapsulated within it. You also learned how to pass values to the component and emit values back up to the consuming component. You also learned how to connect to a Firebase Realtime data store and read and write from it. That’s pretty good for a couple of hours of work!
Do Even More with React, Firebase, and Okta for Secure Authentication
Check out more tutorials on these subjects:
- Braden shows some Chuck Norris jokes.
- Matt Raible takes you mobile with React Native.
- Matt also shows you how to build a backend for React in Spring Boot.
- Braden shows some React Redux.
- Heather discusses being a generalist vs. being a specialist.
Published at DZone with permission of Lee Brandt, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.