Over the following pages, we will build a React app from scratch using a online shop called 'Plants Direct'. Along the way, coding challenges will be set to reinforce what you've learnt.
We recommend using React Create App. Use this build tool npx
with the command create-react-app
followed by the name of your project.
npx create-react-app plants-direct
Change into the plants-direct
folder that was just created. Then you have to install all the node modules the build tools uses with npm install
. I had to manually install npm install web-vitals
manually. Finally start the local development server with npm start
and visit http://loclahost:3000
and you should see the greeting screen!
Feel free to delete the greeting and let's turn our attention to the data state. The data state is central to our app. Without it, React has nothing to display or dynamically update. Each component can have its own state if needed but for now, we'll add state to the global React component we have created.
In your src directory download the data source we'll be using here products.json
. You can use the command line tool called curl
to grab this copy and paste the command below and run it on in your terminal.
curl https://raw.githubusercontent.com/MultiverseLearningProducts/swe-solutions/main/swe2/mod1/starter/cdn/src/json/app.json --output ./src/products.json
Load this data into your React app's App.js
file so it looks like this.
import data from './products.json'
function App() {
return (
<div className="App">
{data.products.length} products
</div>
);
}
export default App;
You should see the text '3 products' in your browser window.
Let's move on and create our first component. One of the great strengths of frontend frameworks is the ability to turn a collection of HTML into a component that can be reused and centrally managed. Let's turn our product HTML into a Product component. Create a new file called Product.js
this file will be our Product
component, we can then iterate over our array of 3 products and use the component to display each item in our data.
// Product.js
export const Product = (props) => {
const {
name
} = props.product
return (
<article className="product">
<h3>{name}</h3>
<img src="./images/boston_fern_sm.jpg" />
<p>
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam eaque ipsa
</p>
<ul>
<li>Likes moisture</li>
<li>Easy care</li>
</ul>
<p>£6.99</p>
<div className="promo-blocks__actions">
<a className="button--anchor">
Full Details
</a>
<button>
Add to cart
</button>
</div>
</article>
)
}
Notice, its just a javascript function. The function returns HTML (some subtle differences like className
not class
why do you think this name has to change?). The input, the props
property, references all the items that are passed into the component. You will see in the next code sample how this javascript function is called (spoiler 😜 it will look like HTML). In the example above I am using 'destructed assignment' to pull the variables out of the product
object that is passed into the component via the props
argument. More on this shortly.
Now return to your App.js
and iterate over the data and render each product using your new React Product
component.
import data from './products.json'
import { Product } from './Product'
function App() {
return (
<div className="App">
{data.products.map(product => <Product key={product.productId} product={product} />)}
</div>
);
}
export default App;
The first line imports the JSON data. The second line imports your component. The component is exported as a const
in ES6 that means when we import we have to use the curly braces to destructure the const
from the exported object. Without the curly braces destructuring the component we'd end up having to write something like the code below.
import Product from './Product'
// below we would have to reference the component like this
Product.Product
The App
is just a javascript function. It returns HTML, the HTML has javascript embed into it within curly braces. I'm just writing plain old javascript within the curly braces to .map
over an array. What is interesting is the way we call the function that we exported from the ./Product.js
file. We are using it as if it were an HTML tag. HTML can have HTML attributes with associated values like below, onclick
and type
:
<button onclick="function (event) {event.preventDefault()};" type="button">Click Me</button>
React components can have values passed to them in the same way. You can add HTML like attributes with values. In our example above we are adding an HTML like attribute called 'product' and associating that with a value which here is the individual product item that we are mapping over from the array of products.
We are also iterating and creating lots of similar components. React wants us to give each Product
a unique key
. You will see error messages if you fail to do this. I'm using the unique productId
that I can see is in the data object that I'm passing into the component. The key
attribute helps React keep track of everything in the DOM and stops it getting in a muddle.
Refresh your page and you should see the product component is reused and outputted three times. The problem is, most of the information is the same. To solve this, we'll need to make sure all the content is dynamic. To do this, we'll need to reference the data in the Product
component and place the variables that represent different values i.e. price to the correct place in the HTML.
Finish your Product component so all the data gets rendered correctly.
NB: rendering the correct image might be tricky. We will solve this in the next lesson. For now you can reference the first image in the list like this images[0].imageSrc
.
You'll notice in the data we have an array of features yet the features are currently being outputted using static HTML. Can you render out the list items dynamically?
Add a remote stylesheet. In your public
folder add the line below to your index.html
file. You can also create your own stylesheet and as long as it's in the public folder you'll be able to reference it like this href="/style.css"
(assuming you called your style sheet 'style.css').
<link rel="stylesheet" href="https://gitcdn.link/repo/MultiverseLearningProducts/swe-solutions/main/swe2/mod1/starter/cdn/src/css/styles.css"/>
Please feel free to style this app however you like as we make it together.