React Scaffolding and File Structure Best Practices

We put the foundations of the Dinosaur Search App in place such as creating a new React app and exploring the supporting API

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the Beginner's Guide to Real World React course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Beginner's Guide to Real World React, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Beginner's Guide to Real World React
  • [00:00 - 02:27] project setup and scaffolding. You may be unsurprised to learn that dinosaurs are quite old and that there isn't much data around for a fair few of them. What is a little surprising, however, is that there are zero live APIs out in the wild that deal with dinosaur exclusive data, say it like the dog API we used in one of the earlier modules. But, fear not, because I've got you covered. In the accompanying course material, there is a starter project for this module that includes a client and a server folder. We'll be building everything that we have planned in the client folder, but the server folder houses a fully functional, node- based API that we'll provide us with, or the dino data that we need. We're going to quickly spin up the API server and take a brief look at the queries that we can make in the sort of data we'll get back, as well as how to start it. If you're interested in learning more about this node server starter kit, I have a helpful article on this very subject on my website. There's also a link to the starter API project on my GitHub too. So let's open and run the starter project. Here's where you can grab the project files for this course if you haven't already done so. You'll need them for this last module as they include a small node-based API server that we'll be using for this module, but not building from scratch. Once you've downloaded the project files, I'd recommend creating a new folder on your local machine to house them. For example, I created the following empty folder on my local machine called code demos dino-search-app. Copy the contents of the module_10/start folder into your new local folder. When you're finished, you should have a folder structure that looks like this. Dino-search-app, and then under that, slash client, and slash server. Open up the project in VS code, are your favorite editor, and let's take a look at the API files. In the data folder, we have a dinos.json file. If you take a look at this file, you'll find a huge list of around 50 plus objects that each represent a collection of information points for a particular dinosaur. Each has a unique ID value, name, location, image file name, and some other relevant info. Open up the server.js file, and you'll see the bare minimum required to get an express.js powered node server up and running. This file creates a server app and plugs in the /roots/root.js file, which serves various API endpoints. The other thing to note here is that we explicitly define a static images root that will allow us to serve images directly from the API's image data, rather than a set of JSON results, as with the dinosaur data.

    [02:28 - 04:45] In the front-end client app, we can call this endpoint like /images, image_name, dot jpeg, and simulate grabbing an image from a CDN, rather than having to house the dinosaur images locally in our front-end project where they don't really belong. If you look in the roots folder, we have a main root. js file that collects the other two files in this folder, dinos.js and login.js, and plugs them into the express.js server that we just outlined. The login.js file serves a single root, API/log ging. It's fairly dumb in its operation. If there is both a username and a password value supplied to it, it will generate a dummy, jot-talking, for us, and returns us to the caller. If neither is supplied, then it returns a 401 error to indicate the user is unauthorised. Of course, this is not in the least bit secure or hooked up in an actual authentication system, but it will serve the purpose of simulating one for our front-end client app, which doesn't need to worry about the backend implementation anywhere, just what's returned from the API. In the dinos.js file, it's where the API cat ers for all the dinosaur related endpoints. It handles API/dinos for fetching all dinosaur information, API/dinos/search, and then a term parameter for fetching the filtered list of dino information based on if the term parameter is a single character or a name of some sort, and then /api/dinos and then the id parameter for grabbing a single dinosaur object. We don't need to go into great detail about the inner workings of the API setup here, you can refer to my article on this exact thing if you're curious, but the basic operation is that each API endpoint uses the node fs function to read the dinos.json file. Depending on the endpoint call, the resulting jason data is filtered and formatted, and then returned to the caller as jason data. Before we plow on with the front -facing client app, let's quickly spin up the API server and check that it's working okay. In your terminal, navigate to the root of the server folder, if this is the first time you're running it, then you'll need to install the dependencies with the following command, yarn install. Once that 's finished, run the star command, yarn start. Nothing exciting will happen at this point, but you should see a message in a terminal saying listening on part 4000, which means the API server is running.

    [04:46 - 05:55] Once we've created the client app for the dinosaur search in one of the coming lessons, and we're ready to run it, you'll need to make sure that this API is running before starting the client app. Don't worry, I'll remind you at the right time, but it doesn't hurt to make a mental note here that you'll need to jump into the server folder and run the yarn start command first. If you open up a browser and navigate to localhost 4000, you will see a white screen with the message welcome to the development dinosaur API server displayed. If you navigate to the main dinosaur root, localhost 4000/api/dinos, then you'll see a more interesting result. The list of all the dinosaur information objects return to the browser as JSON data. I'm using Firefox here so your display may vary, but the idea is the same. Now that we have a good idea of what's what with the API server part of the project, we need to focus on building the front-end client app in our beloved React. Once again, we'll be calling the create react app project to get us off to a best practices flying start. Since we've already got a starter folder and a folder client where we want our front-end files to live, using the default create react app project command can be a little more cumbersome, but let's walk through it and we'll make it out of the other side unscathed.

    [05:56 - 06:38] Open up a terminal window to the dinosaur project folder and leave it at the project root, the one at the same level as the client and server folders. Now run the familiar command yarn create react -app dino -search -app Once it's finished, open up the folder on your machine and cut and paste all of the contents into the client folder. Once this is done, delete the dino search app folder as we don't need it. Now that we've got a shiny new create react app instance installed and ready to go, let's move through the same bits we have in the past lessons and clean up the default files a little.

    [06:39 - 08:24] Open index.js and remove the reference to the import index.css file, delete the source index.css and source app.css files and open the main app.js file and empty it so we can add our demo specific code later on. We'll need to add a few dependencies to our app now, normally Axios. Our old friend Axios will help talk to the dino API and fetch the important fossil data for us. Bulma, no surprises here, Bulma will add nice styles and look and feel to the UI for us. React root at DOM, again we'll be leaning on this package to root our users between pages and areas of the app. At fort awesome slash font awesome dash free. This is a new one but the popular font icon library provides support to Bulma allowing us to display some nice icons along with the dinosaur information. And node dash sass. We've used node dash sass previously to compile our dot sss files into the browser usable dot css files. Let's work through them adding them all to the project by the familiar yarn add then dependency name syntax that we know and love. You could add them all at once by chaining their names onto the end of the yarn add command if you wish but I'm adding them one by one here for clarity and to ensure that there's no mistakes that could be caused by misspellings or typos. Note that we'll add the node dash sass dependency as a dev type. It's not the end of the world if you don't but if the app doesn 't need it to run then it's a good idea to add it here. Now we need to wire up a proxy. This is going to be an unfamiliar part of the process that we've not covered yet. However the create react app scripts offer a special property proxy that you can add to your package dot jason file.

    [08:25 - 10:21] Open up the package dot jason file and add the following line at the end of the file. So we're going to type proxy and then http localhost part 4000. Essentially the proxy property here allows you to proxy requests between front and back end apps that are using the same part. It's something that can happen more frequently in local development scenarios. Our front end app and the API we're calling out running on the same part but this does have the added benefit of not having to deal with irksome cause errors and blockages especially when we don't have any securities concerns at the moment since we're running everything on our local sealed off machines. Also it means we can avoid writing longer API URLs because the value we add here is automatically prepended to the requests that aren't of a text or HTML in nature. e.g. API calls. You can read more about the proxy function in the create react app documentation. Next we'll be using a little cartoon dinosaur mascot as our logo in a few places throughout our app. Normally this little guy . You can grab him from the finished course files or download him from this lesson text. Simply right click and save him somewhere on your desktop. Make sure to name him cartoon dash dino dot png and copy him into the client slash public folder in your project. With all of our dependencies added in our proxy setup let's create all the files and folders we need for the project and build them out. Index.js included out of the box we only need to bring in a redox provider component here and wrap it around our app starting point. App.js another default component but we will be building this out as a centralized routing station of sorts to handle navigation route matching to the correct components via the react router library. Services slash api.service.js the first of our service layer handlers that we're introducing to act as a clean middleman that will handle api requests for other parts of the app returning necessary data for us.

    [10:22 - 11:31] Services dash auth dot service dot js the second date handling service helper the auth service will handle any user sign in requests calling the api for us and any redox interactions that we need as part of it. We'll also offer two custom hooks that we'll explore in more detail as we build out the code. Services slash dino dot service dot js the final service helper will handle requests to the api for dinosaur related data and update any relevant redox calls for us too. Redox slash auth reducer dot js. Just as in the previous module on redox the auth reducer will deal with updates to the auth specific slice of global app state. Redox slash dino reducer dot js another reducer that will deal with the dinosaur information updates to global state. Redox initial state dot js again just like we had in the redox module initial state offers a good blank slate starting point for our app's initial global state and redox slash reducers dot js this will be almost identical to the same file in the previous module. Its function is to pull together the separate reducers and combine them all wrapping everything up in an exported provider component.

    [11:32 - 13:10] Assets slash styles dot s css nothing flash here just a dot s css file that pulls in the font awesome and Bulma styles and adds a couple of helpful styles for some of the components we'll be building later on. Components slash dino browse dot js x when built this component will render a list of dinosaur information card elements and allow the user to search by name or alphabetical letter category. Components slash dino card dot js x a semi-presentational component that will display relevant dinosaur information in a tidy and clear manner and allow users to favorite a dinosaur. Components slash dino details dot js x this will be a much larger component that handles retrieving data for a specific individual dinosaur and then displaying it again allowing the user to favorite or unfurried the dino in question should they choose. Components dino search dot js x a relatively simple component with some scant logic that display the search box and a couple of buttons to allow the user to search for a dinosaur by name this will also represent the homepage for our app and components favorites dot js x the favorites component will display a list of dinosaurs in a similar fashion to the dino browse component the difference here is that it will retrieve a list of dinosaurs to view from the favorited information held in our global redook star. Components layout dot js x with this component we're effectively adding a style structure around the other child components it'll contain app wide UI that includes things like a header and navigation as well as some global spacing elements it's also a purely presentation.

    [13:11 - 14:58] Components login form dot js x perhaps unsurprisingly this is what we'll show our users when they wish to sign into the app it'll house a simple username password form and pass these details onto the API via the service handlers and finally components navigation dot js x another semi-presentational component that will provide an app wide navigation element containing various react routes and link components that ferry our user around the child pages and areas within our app. Now we're clear on what we'll be building and we've created the bare bones of the files let's work through them and flash them out. Let's start with the styles dot s css file open up the assets styles dot s css file and copy in the following styles. The import statement at the top of the file brings in the Bulma css framework styles into the project the rest of the file should be fairly clear we don't have any tricky styles or crazy css wizardry here the remaining styles are helpful to handle the oddly shared images that we have for our dinosaurs setting background sizes and such we also remove some unsightly underlines for around the favorite icons we'll add in later on index dot js there's barely any work to do in the index dot js file we just need to bring in the star provider that we'll create in the next lesson and wrap it around the app component open up the file and let's import the star provider at the top of the file. Next just wrap this component around the app component as we did in the last module and save the file. That was done here so let's move on to the last edit in this lesson. Our app component is a routing office of sorts it's not going to house any logic but it will contain the main navigation routing pattern their corresponding components that handle them. Open up the empty app dot js file and let's bring in the imports.

    [14:59 - 16:23] We're bringing in a lot of tools from the reactor rooted dom toolbox here to help us with routing just as we did in the reactor router module. Next we have our styles file to help applying Bulma to our app and finally we're bringing in all of the components we'll need to handle various routing scenarios as per our user flow diagram. Don't worry that we haven't built these files out yet we'll be doing that in a couple of lessons time. We can bring them on board here because we won't need to edit the app component any further and at the moment none of the components will need any additional logic to be carried out here either. Now let's add in the body of the component and set up the route handling. As a general rule you should wrap your app in the router components or each major part of the app is large enough to justify this approach which is what we're doing here. By doing this we allow the child parts and components of our app access to the reactor router system. For example this is useful for how we're using it with the layout components which is added just under the router one. When we build it out later on it will contain navigation element that uses some of the other hooks and features of the reactor router system. In order to make use of these we need to provide access to reactor router's main component higher up in the component tree just like we're doing here. After this you'll recognize the switch component that we've used and the switch component is designed to match and render routes exclusively.

    [16:24 - 17:09] In practice what this means is we have more precise control over what is rendered for each route. We have very distinct route handling needs here for each separate page in our dyno searching app. Switch helps us to make better matches against each navigation route or user visits. You can read more about switch on the reactor router docs. Inside of the switch component is the maintenance potatoes of our route matching system. You can see that we have a number of mostly self explanatory routes that will render the components we imported earlier depending on the route they choose. You can recognize the route parameter format from the module on routing earlier in the carse here too. Routes like browse, call on name, will match URL such as browse , an interesting name or browse 123. Nordes 2 how are listing route paths in order more specific to least specific.

    [17:10 - 17:42] The switch component works in this way too so we're mirroring that. We're not making much use of this system here by supplying different components for the same route but which features a parameter but you may want to in other apps so it's useful to see an ideal approach to handling that scenario. Nordes that in this app we've decided to just hard code the route paths as strings. In the module on routing we opted to pull our route from a route.js file and dynamically loop through them. To keep the overhead a little lower in this more complex dyn o app we've chosen the direct paths as a string approach but you could just as easily use whatever method you like.

    [17:43 - 17:57] As long as each route component has a path attribute to match against a URL and a component attribute to know what to render when the path matches the routing system is happy. So each route component here matches a path and renders the correct component to handle it.

    [17:58 - 18:16] We have one final non-explicit route which will be rendered if nothing else matches. For example if a user navigates to forward slash apples we don't have a matching route for that and this catch all block of JSX will be rendered. It's just a simple h1 element explaining the classic 404 page not found message and giving our users a way out back to the safety of the home page.

    [18:17 - 18:42] With everything finished in the app component the whole file should look like this. And that's all there is to the app component. It's a navigation route handling train station passing the user to the correct component for their selected route. In the next lesson we'll work through the services and redox files to put the data handling and underp innings in place that will support our UI components.