Phase-2/ react
During my time at Flatiron School, after completing Phase-2 of learning React, understanding and creating functionality became easier and easier. Through out this phase, I learned about components, props , hooks and much more. One thing that I really loved learning about was client side routing. After gaining skills through labs and learning through code walkthroughs and reading the articles throughout phase-2. I’ve managed to build a cool React App for the “Rusko’s Auto Sale“
The “Rusko’s Auto Sale” App
When the homepage loads, the Car page renders with all the available vehicle cards are displayed on the screen. Also allows users to favorite and un favorite cars.
The car page includes a filter feature that lets users search for vehicles by make or model. It filters all the cars based on what is typed in the text box.
When the user wants to send a private message to the seller of a vehicle, all they need to do is click the link for that vehicle. Once the linked is clicked. A page for that vehicle appears on the page.
Once the user submits a message a little sent message pops under the form.
To go back onto the home page the user has to click the ‘Home‘ link
If a user wishes to list a car. On the home page all the user has to do is press the “List Car“ button
This page renders when clicked
When the user fills out the form and clicks submit A little message pops up under the form with the users name year of car, make and model
Then when the user clicks the back button the car page renders. with the newly listed car below
Then the user can click the “About“ link to see the About Page
and the “support” link to see the support page
When the user fills out their information and clicks submit a little message pops right under the form
Walking through my code
The first thing I did for this project is create a new folder with a db.json file. This file will be my backend for the project which stores all of my data for the vehicles which ill be using throughout my code.
After creating that folder, I then created my frontend folder. I used create-react-app to start building and organizing my folders within it.
As seen above there is a components folder and a pages folder. Under the pages folder you can see that I created a routes.js file. I first installed react-router-dom. then I imported All of my pages that would use client-side-routing.
In the snippet above, I created an array containing five objects. Each object includes a path, an element, and an errorElement.
path: The URL path to match.
element: The page to render when the path is matched.
errorElement: The page to display if an error occurs.
Then, I exported the routes array.
As shown above, I imported the createBrowserRouter
function and the RouterProvider
component from the react-router-dom
library. Then, I imported my routes
array from routes.js
.
createBrowserRouter: This function takes the routes array from
routes.js
and creates a router object based on the defined paths and pages.RouterProvider: This component takes the router as a prop, allowing navigation throughout the app.
Finally, the app is rendered into the root DOM element. The RouterProvider
enables routing across the app.
Making my NavBar component
In my NavBar.js
file, the first step was to import the NavLink
component from the react-router-dom
library. I created a <nav>
element to serve as a navigation bar. Inside this <nav>
element, I defined three NavLink
components. Each NavLink
uses the to
prop to specify the URL path it links to.
- to: Defines the URL path that the link will navigate to when clicked.
Finally exported it and imported the NavBar
to my Home
, About
, and Support Us
pages.
Building my Home Page
In my Home.js
file, the first thing I did was import my useState
and useEffect
hooks from React. Then, I imported my custom Header
, NavBar
, CarForm
, and CarPage
components. Next, I set up state variables for managing the form’s visibility (isFormOn
) and storing the list of cars (cars
) with an array.
The handleClick
function toggles the visibility of the CarForm
component when the button is clicked.
Within the useEffect
hook, I first fetch the car data from the server at http://localhost:3001/Cars
, converting the response to JSON and updating the cars
state with the retrieved data, storing it in the cars array with setCars(data)
.
The addCar
function allows me to add a new car to the existing list of cars by updating the cars state using setCars([...cars, newCar])
.
Lastly, I returned some JSX. After rendering the NavBar
and Header
components, I created a button that dynamically changes the label based on the form's visibility. If the form isn’t displayed, the CarPage
component is rendered; otherwise, the CarForm
component is rendered.
Building my Car Form Component
The code is too long to put a full snippet here so ill show the handleSubmit
function
I first prevented the form from reloading the page on submission. Then, I created a new car object with keys matching my current data structure, assigning each key the value of the corresponding state variable.
After that, when the user clicks the submit button, a POST
request is sent to http://localhost:3001/Cars
to add the new car to the database. I included the necessary headers and set the body to convert the newCar
object into JSON
. Then, I used the onAddCar
function, which I passed down from the HomePage
as a prop, with the newly created car.
Building my Car Page Component
In my CarPage.js
file, I imported the useState
hook to create a state variable for managing the user's search input. The onSearch
function updates the state whenever a new search term is entered.
Next, I filter the cars array to find vehicles that match the car make or model, ignoring case sensitivity. This filtered list is stored in a variable called displayedCars
, which helps avoid having two sources of truth when I pass it as a prop called cars
to my CarContainer
component. I also passed my onSearch
function as a prop to my Search
component.
Search Component
In my Search.js
component, I made sure to pass down the onSearch
function from the CarPage
component to update the search term with the current input value in my handleChange
function. This way, whenever the user types into the input bar, the search term will always match the current input value.
Building my Car Container Component
When I passed down my cars
(displayed cars), I used JSX to use an array iterator “.map
“ which allows for every car object of the array to render a CarCard
component. Then I passed a prop called car
.
Car Card Component
Below shows the structure of my CarCard
component.
As you can see above, I created a button to favorite and unfavorite cars by creating a fav
state variable. When the button is clicked fav
toggles from true to false. Also, The class name and label changes depending on the value of fav
.
I also imported the Link
component from the react-router-dom
library. I set the to
prop to create a path to /carseller
with the selected car's ID. So for each of the car cards the user will be able to click the send private message
link which renders that page for the selected car.
About and SupportUs pages
My About.js file is simply put together. I made sure to add my NavBar
so users can navigate through the page and my custom Header
component. Along with some description and an Image.
In my SupportUs.js
file, as shown above, I created a form. I used conditional rendering to display a thank you message based on the state value isSent
. I also added my custom NavBar
and Header
components, so the user can navigate and see the header throughout the page.
Styling
Above is my styling for my NavBar.js
file as you can see above
Below is my styling for all my other elements throughout this app witch is in my index.css
file. My time building this project I for sure learned more about styling than ever.
In this file, I wrote up to 160 lines, so I won't show all of my styling. You can click the link below to check out all of my code that I didn't cover in this blog.
https://github.com/Hass3/react-project-frontend/tree/main/ruskos-auto-sale-app
Conclusion
Building my skills in React.js throughout Flatiron School has been quite challenging. Although it was tough at times, it was definitely worth it. Now I can comfortably create frontend sites with the knowledge I've gained from this phase. The skills I learned through the labs and code-alongs have been a huge help. I'm still learning as a young developer and can't wait to see how far my skills will go after finishing the program and in the years to come.