We will be building the front-end for an app that lets users view information about parks, and the trails inside each park. Users can also leave reviews for parks and trails.
Use this GitHub repository to follow along or use as a reference. I recommend forking and cloning so you have your own copy. There will be a branch for each part of this tutorial that will have the complete solution for that part. So if you switch to the 'components' branch, you will see all the code that this part of the tutorial will end with.
Now that you have the repository cloned onto your computer, navigate inside of the essential-react-tutorial directory and, in your terminal, and run this command:
$ npx create create-react-app .
This command creates everything you need to quickly start using React, without it we'd have to cover a lot more material to setup. Using the Create React App project is ideal for learning React, so we can jump straight into coding. You can visit the docs for create-react-app to learn more about it.
If you enter
$ ls in terminal, you should see this:
Everything is setup! We can now run
$ yarn start to start the server and start building our app!
In your browser, go to localhost:3000. Keep the server running, your browser window will automatically refresh when you save changes in your code!
The very first concept to understanding react, is knowing about components. What makes any library/framework worth using is following the conventions to have DRY, maintainable code that boost your productivity. With React, parts of the UI (user interface) will be split into components to isolate how we will handle the data, structure and functionality around that part.
For example, the app we are going to be building will focus on content around parks, trails and reviews. At minimum, each one of those will have it's own component. They will have their own set of data, functionality and design. As we continue to develop, and as those components start getting more complex, it is very likely some parts inside those components will need to be split into new components. For example, with reviews we are going to want to display reviews and be able to submit a review with a form. Those are going to be two separate components.
Everything we need is in the /src directory. In app.js, we already have our first component. Notice that it is setup as a function, where it returns everything we want this component to render. The component is defined in this file, but only having the code in this file is not what is making it show up in the browser.
Instead, in index.js, notice line 4 & and 9 (can reference in photo below). Line 4 is importing the component from the app.js file. That gives us access to be able to render the component on line 9. Now, notice how it is being rendered. Using HTML-like syntax, it's able to be called with the name of the component in a self-closing tag. This syntx is JSX.
Create New Components
It's time to get to business and start building out app! We will start by creating a new component for park, trail and review.
To keep our files more organized, start with making a /components directory inside of /src:
$ mkdir src/components. Lets go ahead and create a file for each of our components, within our new components directory:
$ touch src/components/Park.js
$ touch src/components/Trail.js
$ touch src/components/Review.js
Open the new Park.js file you created. Based on what you saw with the App component, what is the minimum code needed to be able to import this component to another file to render? Click here for the solution.
We made the component, but now we have to explicitly call the function to tell it where to render. Let's go back to App.js, import Park.js at the top, and then use JSX to render the Park component. I suggest removing the code on lines 8-21, in App.js. Click here for the solution.
Right now, your localhost:3000 should be showing 'I'm a park!', or whatever you returned from the Park component. Your code should look like this:
Note that when defining and calling a component, the component name has to be capitalized
Use this same pattern to build the Trail and Review classes. They should look something like this:
Load Components within Each Other
If we want to be able to see trails that belong to a park, it makes sense to load trails within parks. How would you do that? Try it out! Refer to this solution if you get stuck.
Now do the same, but with Park and Trail each having a Review component render with it. You might run into this parsing error:
Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?. When returning from a component, all elements must be wrapped in a single element (typically a div or section).
If it doesn't make sense to have a wrapping element, use React.Fragment to wrap around the elements instead, when returning. Fragments won't be used in this tutorial, but they're good to know about. Look at this page of the docs to know when it's appropriate to use.
This is a good spot to pause and make sure everything mentioned so far makes sense. Refer to this solution and the image below for where your code should be at this point.
A Note on Functional vs Class Components
This project is going to strictly use functional components. Before React Hooks were released in 2019, using ES6 classes were typically preferred for more complex components. Many code examples and code bases built before then will likely use class components. It's good to be aware of when searching for help online and when working in other code bases. This topic can lead you down an entire rabbit hole but, for now, just know that when a component starts with 'function' it's a functional component, and when it starts with 'class', it's a class component. Easy peasy!
The next section of this tutorial will cover handling data between components