Practical React & Redux - Part 1
Tags: react, redux
Published: 2020-04-24 13:00:15

_Originally published at [Codegram's blog](https://www.codegram.com/blog/practical-react-and-redux-part-1)_

At Codegram we can spend 5 hours a week doing some learning stuff like reading books, doing an online course, or even crafting some pet project to try a new technology. It's really cool and sometimes we even share with our coworkers what are we doing in our biweekly Codegram's Talk Club™️. We want to make a step forward and we decided to create a new learning resource: introducing Codegram's Workshops™️!

Today we are gonna talk about React and Redux. In this first article of this workshop series we are gonna learn how to bootstrap a React application and create our first components. Stay tuned for future updates in this workshop series and let's start!

## Introduction

This course is an introduction to [React](https://reactjs.org/) and [Redux](https://redux.js.org/). We are gonna learn how to create a react application from scratch and deal with components and their weird JSX syntax.

This is not a complete React course and I want to focus on the basics and how to work with a store. I am not gonna cover some topics like styling your components or testing because these are broad topics that can be covered in future workshops. Even though we are gonna use Webpack I am not gonna cover any complex setup either. Let's begin!

## Getting started

First of all we need a React application to start working on! There is a package called [create-react-app](https://github.com/facebook/create-react-app) that is very useful to bootstrap something. You can run this command:

```bash
$ npx create-react-app --use-npm practical-react-and-redux
```

By default the command uses `yarn` but I prefer `npm`. Let's move to that directory and start the development server:

```bash
$ cd practical-react-and-redux
$ npm start
Compiled successfully!

You can now view practical-react-and-redux in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.1.12:3000

Note that the development build is not optimized.
To create a production build, use npm run build.
```

This will open your browser automatically to [http://localhost:3000](http://localhost:3000) and if you see the React logo spinning then the application has been compiled successfully and we are ready to start doing some stuff!

Spin up your favorite editor and move on 👏

## Components are just functions

Let's start our journey creating our first component but, first of all, what's a component? In the React world a component is just a function that returns something that can be rendered in our DOM. Open the `src/App.js` file and remove everything.

### Hello world components

We are gonna create our first component: the `App` component. Every React application has a root component and although you can name it whatever you want it is usually named `App` or `Application` (notice the `CamelCase` syntax). Write this in your `src/App.js` file:

```jsx
// src/App.js
const App = () => {
  return 'Hello World!'
}

export default App
```

If you visit the [http://localhost:3000](http://localhost:3000) you will see our message. Congratulations you just write your first component! 🎉

You are not limited to just `Strings` and you can also write plain HTML in there. Try this:

```jsx
// src/App.js
const App = () => {
  return <p>Hello world!</p>
}

export default App
```

Oh snap! Our application is not working anymore and we got a compilation error. What did you expect? Do you think that looks like JS? Of course not!

There is so magic ✨ behind of this. First of all we are not using plain JS anymore and we started using `jsx`. That's a language that compiles to JS and you can think about it as a hybrid between JS and XML (or just HTML).

In order to make that work we need to bring React to the party so let's import it!

```jsx
// src/App.js
import React from 'react'

const App = () => {
  return <p>Hello world!</p>
}

export default App
```

You might be thinking: why I am importing the React constant if I am not using it? That's true! We are not using the `React` constant explicitly but when Webpack compiles this `jsx` it's using `React.createElement` under the hood to create our component so we need to bring that constant to make it work. If you are curious you can check the `main.chunk.js` source file in the browser.

A single component is really boring so let's create a few more components!

### Components hierarchy and reusability

Time to create a `Dog` 🐶 component! As you may notice there is no folder structure to follow but I like to stick to some conventions. I like to organise my components per feature and also having each component in its own folder:

```bash
$ mkdir -p src/dogs/components/dog
```

In your editor create the `Dog.js` file in the new folder that we just created with the following content:

```jsx
// src/dogs/components/dog/Dog.js
import React from 'react'

const Dog = () => {
  return (
    <div>
      <p>Boira</p>
      <p>Score: 13/10</p>
    </div>
  )
}

export default Dog
```

Now we can use this component in our `App` component like this:

```jsx
// src/App.js
import React from 'react'
import Dog from './dogs/components/dog/Dog'

const App = () => {
  return (
    <>
      <Dog />
      <Dog />
    </>
  )
}

export default App
```

You might be wondering what's that ugly thing: `<>`. That's an empty tag and we need that for two reasons:

- Every React component needs a single root element.
- We don't want extra markup so the `<>` root element is not gonna render anything

Then we are just rendering two `Dog` components. As you can see a component can be used as a simple DOM element. We are enhancing the HTML language adding new tags!

Having two dogs named after my dog Boira is cool but it is cooler if we can change dynamically some things in our components. Enter the `props`!

### Dynamic components using props

A prop or a property is a component's input data. Remember: components are just functions so props is just the single argument that our function is receiving. Since it is an `Object` we can use destructuring like this:

```jsx
// src/dogs/components/dog/Dog.js
import React from 'react'

const Dog = ({ name, score }) => {
  return (
    <div>
      <p>{name}</p>
      <p>Score: {score}/10</p>
    </div>
  )
}

export default Dog
```

We added the two props: `name` and `score`. We are also using those variables inside our template escaping the value using curly braces `{}`.

If you refresh the page right now you are gonna see nameless dogs without score and that's very sad. You can think about props as a object that include all HTML attributes given to the DOM element representing your component. In other words, you can set the element of these props giving attributes to the `<Dog>` tag:

```jsx
// src/App.js
import React from 'react'
import Dog from './dogs/components/dog/Dog'

const App = () => {
  return (
    <>
      <Dog name="Boira" score="13" />
      <Dog name="Black" score="13" />
    </>
  )
}

export default App
```

The application works and we have two different dogs now! There is one problem with our current implementation: we could forget to give a value to the `score` prop and a dog could end having a `null` score 😱.

### Props validation: avoid bugs

React doesn't include a built-in package for props validation but there is a package called [PropTypes](https://www.npmjs.com/package/prop-types) that is included by default when we created the application. We can use this package to validate our props and ensure our components are used correctly:

```jsx
// src/dogs/components/dog/Dog.js
import React from 'react'
import PropTypes from 'prop-types'

const Dog = ({ name, score }) => {
  return (
    <div>
      <p>{name}</p>
      <p>Score: {score}/10</p>
    </div>
  )
}

Dog.propTypes = {
  name: PropTypes.string.isRequired,
  score: PropTypes.number.isRequired
}

export default Dog
```

If you reload the app the application, it is working but we have an error in our console 🤔. We just found a bug! 🐛. In the previous snippet we added prop validations and marked both props as `required`. We also marked our `score` as a `number` but we are giving it as a `string` right now. Let's fix this:

```jsx
// src/App.js
import React from 'react'
import Dog from './dogs/components/dog/Dog'

const App = () => {
  return (
    <>
      <Dog name="Boira" score={13} />
      <Dog name="Black" score={13} />
    </>
  )
}

export default App
```

The change might be a bit subtle: we replaced `"13"` with `{13}`. Since we are using curly braces again we are evaluating that `13` as a Javascript `number`and the error is gone!

### Event handlers as props

New requirements: we want to add a button to increase that `score` (we are not gonna add a button to decrease it because dogs are awesome). We need to listen to the `click` DOM event for a button and lucky for us React supports a `onClick` prop. Let's see how this works!

```jsx
// src/dogs/components/dog/Dog.js
import React from 'react'
import PropTypes from 'prop-types'

const Dog = ({ name, score }) => {
  const onClick = () => {
    score += 1
    console.log(`This is your new score: ${score}`)
  }

  return (
    <div>
      <p>{name}</p>
      <p>Score: {score}/10</p>
      <button onClick={onClick}>Increase score</button>
    </div>
  )
}

Dog.propTypes = {
  name: PropTypes.string.isRequired,
  score: PropTypes.number.isRequired
}

export default Dog
```

Don't click the button yet! Let's check the code first. We added a new `button` element to the template and added the `onClick` prop. That prop needs to be assigned to a callback function that will be called when the user presses the button. I added a new function called `onClick` (naming is hard sorry) and I am increasing the `score` prop and logging a message.

If you visit the page and click the button you will see the message prompted in your console with the new `score` value. Yeah you did it! Oh...wait. The template is not being updated, we have another bug! 🐛

Not really 😅, props are supposed to be `read-only` and our `Dog` component is `stateless`. We need to make our component `stateful` to be able to change that `score`!

Just a quick warning ❗️: When a component's prop changes the component is automatically re-rendered but in our case we are not really changing the prop so the view is not updated.

## Conclusion

In this article we learned about how to create a React application from scratch and added our first components. In the next article we are gonna learn about `stateful` components using React hooks and also we are gonna do our first steps with Redux.

You can find the code examples in this [repository](https://github.com/codegram/practical-react-and-redux). I also tagged the progress for [part 1](https://github.com/codegram/practical-react-and-redux/tree/part-1) in case you want to check the repository at this specific moment.

_Cover photo by [Lachlan Donald](https://unsplash.com/@lox?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)_