Getting started with React

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.

Learning Objectives

React Create App

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!

React spinning logo

Establish a data state

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.

Create your first React component

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>&pound;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.

Assignment - Coding challenge

Part 1

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.

Part 2

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?

Part 3

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.