- Home
- From my desk
- Example React Web App
Today we will be creating a very small React app that will show 3 items we have for sale. The full project is available and illustrated throughout this post. In this example we will be introducing React, state, and side effects using functional components. The sample project acceptance criteria is:
- Display 3 items for for sale
- Favorite and unfavorite an item
- Remove / delete an item
JavaScript
It is important that you have a solid understanding of vanilla JavaScript before working getting started with React because React is just a framework written in JavaScript. It is not its own language. React uses a combination of CSS, JS, and HTML in order to create UI elements for the web, mobile, and more!
Check out a complete demo of the code illustrated below to see what the fully functional React app looks like.
Setup
In order to get started with React, you need to insure that you have React installed using NPM. If you do not have Node or NPM you will need to install it using NVM.
Once your system is setup for Node development, you will need to start a project using create-react-app, create-next-app, parcel, or a custom webpack setup. Optionally you can do it without any frameworks as well.
Initialization
The first thing we do in order to get started with building a React application is to render an entry level component. We need a div in the app index.html file with an ID of app We do it this way because if we rendered React in the body tag, it could cause a lot of bugs with other JavaScript libraries since those may rely on the body tag.
In the above example, he App component is the main React component. This component is considered our application root. It's in charge of rendering all of the pages and components. When we call the render function, find the div with the id of app in our html, and render the App component with JSX.
Creating a Component
JSX look like HTML but is written in JavaScript and processed through compilers like Babel. When writing a React component, every component must start with a parent component. You can use things like Fragments to contain the JSX, or keep it old school and wrap a div around the JSX. Both are fine approaches.
The above example is doing a few things. First take a look at the name of the component. The component is called ListingCard. In React, custom components start with a capital letter. This makes it easier to read and for the processors to understand the differences between native html, web-components, and custom components. We then assign it to an arrow function that takes an object of custom properties. In React these are called props.
In order to write variables into our JSX, we need to open up curly braces where we want the value to be set. So, where you see curly braces like on line 7 of the img src attribute, that means when the compiler renders this out, it will have the full url value.
Hooks
We also use a hook called setState. In React, we have different lifecycle methods that occur while rendering a component. React exposes a series of hooks for us to use in order to write features that include state management and side effects. Take a look at the hooks documentation for more info on hooks.
The useState hook is called with a default value of false because we don't want the users to like everything by default. If we did then the state would be true by default and we would pass that into the useState hook instead. When we create the toggled state, we get a value with two objects in an array. The first is always the current value. The second value is the function to update the value. We use array destructuring in order to pull those values out of the array and make them more readable. Thats how we are able to name the getter toggled, and the setter setToggled.
Synthetic Events
The last part to this component is wiring up the stars. On line 10 we have a ternary operation wrapped in curly braces within one of our JSX tags. If the value of the toggled state is true, we show an active star. Otherwise we show an empty star.
Each div inside of the ternary operation has an onClick event. This is similar to the JavaScript addEventListener function. React creates synthetic events through its own pipeline. The onClick function will fire the callback function specified in the value of the onClick prop. We wrap the setToggled function in an arrow function because we do not want the function to prematurely fire and update the state without us explicitly clicking on the div.
The exclamation mark in each of the onClick functions "setToggled(!toggled)" means the opposite of the current value. So "!true" means false and "!false" means true. This gives us the ability to toggle the stars on and off.
Exports
The last thing we do is export the component. We export the default so we do not have to worry about destructuring and can simply write "import Component from 'blahblahblah'"vs "import {Component} from 'blahblahblah'."
Adding a child component
Now that we have created the ListingCard component, it's time to add it to the ListingContainer component. In React, it is best practice to split out components into their own files. Then we take each component and compose a page out of them as if they were legos and we were building a castle. Take a look at how we would add the ListingCard to the ListingsContainer.
In the example above we are importing the ListingCard component at the top. In node, all imports should go at the top of the file. Exports should go at the bottom.
Using Props
We setup our function component with the name ListingCardContainer and add add two props. The first is the listings array we will get from the parent component. This array will be used to render each of our listings cards. The second parameter is a function to delete the listing. This will remove the item from from the page when we click the delete button.
Map and Render Children
On line 7 we use the JavaScript map array method because we want to create a new array containing a react component to render. React will automatically render arrays for us as long as they are in curly brackets. So on line 7, when we call the map function, we can return a ListingCard component. The key prop is specific to dynamically rendering with the map function. React needs to know if the map changed so it can rerender the component. Each key prop must be unique. So when in doubt, use the index value of the map.
Passing Props
We set the following properties we specified in the ListingCard parameters. In React, we have to set the values using curley braces. For example "name={listing.name}". That is how you set the value of a prop parameter in React. If you set the value here and did not accept the value in the child component, this will do nothing. You must accept the value and use it in the child component. The last thing we do is set the onRemoveItem value to the onRemoveItem prop that came in from the ListingsContainer component.
Composing the application
The final thing we need to do is get some data from the top level of the application, and compose the page with our components. For the sake of example, I have used a fake.json file when the fetch is down or doesn't work so the example will still function. This part of the code is for demo purposes and is safe to ignore.
In the above example we create an App component. This is the main component that will render our applications content and components. First we import the ListingsContainer and then we render it as JSX on line 29. We pass in two props. The first is listings which is set to the value of data. The second prop is the onRemoveItem callback function.
Hooks & Fetch API
In React we use the useEffect hook to do work that is needed as the component is rendering. The useEffect hook has 2 arguments. The first is a callback function that will fire every time the useEffect needs to call it. The second argument is an array of objects to watch.
When these objects values change, react will fire the callback function again. So if we do not want this to fire the callback during the next render loop, we can set the array to be empty "[]" with no values inside. That means this useEffect will only fire once. Therefor when we load the page, we will fetch our data using the fetch api. We can then call setData to set the state for our data and pass it along to the child components as props, ie "listings={data}".
Callback as Prop
The onRemoveItem function is a callback function that accepts 1 parameter. This parameter is the id of the item we want to delete. When we click the delete button, we need to call this function with the id of the item we are deleting, which we do inside of the ListingCard onClick handler within the button.
Testing
If you haven't downloaded the React Developer Tools, you should def do that right away. It allows you to see the data and alter the state without having to rerun the code and it's great for debugging.
Happy coding!
Last updated: Â 06/23/2022 @ 07:31 PM