Take your first steps in your React journey!

If you’ve already started reading about frontend technologies ReactJS was at the top of every list. That’s because React is really taking over frontend development up a notch and its popularity is growing all the time.

People use React because it’s a javascript library and you don’t have to learn much new stuff to get started with it.

In this article, I’m not going to explain why I think React is the best thing out there, but I’ll try to do a walkthrough to create a very first app with ReactJS.

First, let’s talk about the requirements.

If you don’t have IDE installed on your computer, VS Code is perfect for this and it’s free

After installing VS Code, you’ll need to install node and npm

If you use MacOS you can install them with brew install node

Windows users, node can be downloaded from here their official webpage.

You can check your node and npm versions using these commands

$node -v
v16.18.1

$npm -v
8.19.2

Create React App Command

In a terminal enter this command:

$npx create-react-app [your-app-name]

When you are inside the folder where you want your app to be, you can run $npx create-react-app ./

The script will run and create a project with some files in which a kind of Hello World app will be created. After the script finishes, you can run the following command in the terminal:

npm start

This will start your React app and it will open in localhost:3000

first screen after create react app
First screen after React app creation

Hooray! You’ve just created your very first app and the tutorial is done, good luck!

React App File Structure

All kidding aside, we’ll move on to creating a simple Todo list, but first this is React’s default file structure:

react app file structure
File structure of react project
  • node_modules is a folder where all of the packages you use in React are
    • npm install is a command that installs every package that is included in the package.json file
    • each npm command is documented in README.md
  • public contains the html file where React inserts your content
  • src is where all the magic happens (this is where all the files and components are put)
  • package.json is a file that contains all the packages that the app needs in order to run
  • package-lock.json stores the versions of these packages

First, we can get rid of some files and have the following result

- src/
	- components/ // here we'll put our components which will be rendered in App.jsx
	- App.jsx // .jsx is a file extension specifically for React
	- index.js
	- index.css
	- reportWebVitals.js
	- setupTests.js

So, we need to create a Todo List, and before that we need to create a list of things we want our app to do:

  • create a list of of todos
  • add items to the list
  • remove items from the list
  • handle onClick actions

When you start learning React, you have to start thinking in components. Every page you see on the web can be broken down into components: Header, Menu, Container, Article, SideMenu etc.

In our case, we need a component that displays a list of Todos and each Todo item is also a component. It’s a kind of a design pattern to split your code into components and it’s easier to maintain the code if you that.

React Components

So, first, let’s create a file in the src/components/ folder named TodoItem.jsx

import React from 'react';

const TodoItem = props => (
  <div>
    <p> Todo item text </p>
  </div>
);

export default TodoItem;

This will be the content of our component. The idea is to create a function (functional components) that returns a block of code in HTML (called React element).

Our component can receive props which are properties for this component sent as an object argument. We’ll see later how to send and read props in our app. But first let’s create another file that contains Todo list.

Create another file in the components folder named TodoList.jsx

import React from 'react';

const TodoList = props => (
  <div>
    <div><p> Todo item message 1 </p></div> // Todo item
    <div><p> Todo item message 2 </p></div> // Todo item
  </div>
);

export default TodoList;

We can see that the items in our list can easily be replaced by TodoItem since they have the same content. So we’ll replace these two divs with two TodoItem components

import TodoItem from './TodoItem';

const TodoList = props => (
  <div>
    <TodoItem />
    <TodoItem />
  </div>
);

By importing TodoItem we can use this component inside TodoList. This also allows us to send information from the TodoList component to TodoItem via props.

For example, if we have a TodoItem and a TodoList as follows

const TodoItem = ({ message }) => (
  <div>
    <p> {message} </p>
  </div>
);

const TodoList = props => (
  <div>
    <TodoItem message="test message 1" />
    <TodoItem message="test message 2" />
  </div>
);

This would render two TodoItems with ‘message’ as the text value. Props can be sent under any Javascript type: Object, Array, String, Number, etc. This way two components can communicate with each other (not the only way, but the easiest way).

Following the example above, let us add the TodoList component to our App component so that we can display items in the app page.

import React from 'react'
import TodoList from './components/TodoList';

const App = () => (
  <div>
    <TodoList />
  </div>
);

export default App;

Now we should see two TodoItems in our app as shown in the screenshot below

state of the react app
State of the React app

You can do a lot of things in React using components, here you can find a nice article about creating a component library. Give it a try at least to learn about what Storybook is.

Send Data Between React Components

Next, we need to apply props to our TodoItem and add some other elements, such as a checkbox and a button, so our component will look like this

For the items that we will add, we also need action handlers:

  • onCheck – changes the completion state of our element
  • onRemove – remove a TodoItem

We need to change our code as follows:

const TodoItem = ({
  text,
  isCompleted,
  onCheck,
  onRemove
}) => {
  return (
    <div className="todo-item">
      <div className="todo-item-text" onClick={onCheck}>
        <input type="checkbox" checked={isCompleted} />
        <span>{text}</span>
      </div>

      <button onClick={onRemove}>Remove</button>
    </div>
  );
};

Our component takes props for the text, completion status, and functions to check and remove the item. TodoItem should be responsible only for displaying a text and a checkbox, so we send the actions as props – our parent (TodoList) must handle them.

The class names used in the component are defined in a styling file, which you can view in the project repo at the end of this article.

To display some data by default, I created a hardcoded list of items in the following form

const INITIAL_STATE = [{
  id: 1,
  text: 'Todo item 1',
  isCompleted: false
}, {
  id: 2,
  text: 'Todo item 2',
  isCompleted: false
}, {
  id: 3,
  text: 'Todo item 3',
  isCompleted: true
}];

This will modify our TodoList component and we need to add a local state to it where we can store our items. We also need to define functions that control checking the checkbox and removing an entry. In addition to these elements, we also need to add an input that will be used to store new items in our todo list. This will look like the following:

So let us define the logic for our handlers

const handleOnCheck = item => {
  item.isCompleted = !item.isCompleted; // change isCompleted value for selected item
  setTodoItems(items => items.map(temp => temp.id === item.id ? item : temp));
}

const handleOnRemove = item => {
  setTodoItems(items => items.filter(temp => temp.id !== item.id));
}
 
const handleAddTodo = () => {
  const newItem = {
    id: Math.random() * 1000, // we have to generate a random ID for each item
    text: value, // value will be saved in a local state
    isCompleted: false // by default not completed
  }
  setTodoItems(items => [...items, newItem]); // set items in local state

  // clear input value
  setValue("");
 }
  • using the handleOnCheck function, we toggle the completion state of the item corresponding to the checkbox we clicked.

We do this by inverting the isCompleted property of the item and then updating the state of todoItems to reflect the change.

  • the handleOnRemove function removes an item from the todo list. This is done by using the filter method to create a new array of items that does not contain the item that was clicked to remove.
  • the handleAddToDo function uses the text of the new todo item and adds it to the todo list. It creates a new object for the item with a unique ID, sets the text and isCompleted properties, and uses the spread operator to create a new array with the existing todo items and the new item. The state is then updated with the new array of todo items.

After we define the logic for the handlers, we can write the contents of the TodoList component.

We map an array of items to a list of TodoItem that receives values as props (values from the initial state).

We create an input field that changes the local state of ‘value’ that is used in handeAddTodo

const INITIAL_STATE = [...];

const TodoList = () => {
  const [todoItems, setTodoItems] = useState(INITIAL_STATE);
  const [value, setValue] = useState("");

  /* here we have our handlers */
  const handleOnCheck = (...)
  const handleOnRemove = (...)
  const handleAddTodo = (...)

  return (
    <div className="todo-list">
      {
        todoItems.map(todoItem => (
          <TodoItem
            key={todoItem.id}
            checked={todoItem.isCompleted}
            text={todoItem.text}
            onCheck={() => handleOnCheck(todoItem)}
            onRemove={() => handleOnRemove(todoItem)}
          />
        ))
      }

      <div className="todo-list-add-input">
        <input
          type="text"
          placeholder="Your todo item text..."
          value={value}
          onChange={event => setValue(event.target.value)}
        />
        <button
          className="add"
          onClick={handleAddTodo}
        >
          Save
        </button>
     </div>
   </div>
 )
};
  • useState is a hook of React used to get a local state inside a component. It returns an array of elements that are stored and a setter: const [values, setValues] = useState()

After all these changes, our code should look like this (with some styling up to you):

We can see that our INITIAL _STATE, which contains 3 elements, is rendered as 3 todo elements with the values from our state.

final todo react app
Final Todo React app

Summary

That all I think, we have a Todo app with all basic operations: add, remove, edit.

That’s just the top of the iceberg, a lot of things are happening in the backstage but React world is a beautiful one so all the work is worthing

Some bullet points on this article:

  • React is a library that let you create web applications using components
  • Functional components are the way to go when it comes
  • Props and state is how you can send and store data throughout your application
  • Props are used to send values from a parent component to its children
  • The state is used to store and manage the internal data of a component and can be changed by the component itself using setState. When the state is updated, the component is re-rendered to reflect the changes.
  • React is awesome 🙂

Previous post Next post

Recap of our Festive Celebration at Muura Steak House!

Read More

AI & Machine Learning in Software Testing

Read More

Comments are closed.