React JS Tutorial For Beginners (React Hooks)

React JS Tutorial For Beginners (React Hooks)

In this tutorial you will learn about React JS.

Starting from what react is, why use react, create-react-app, components, click events, useState Hook, looping lists, props, useEffect Hook, React Router, JSON Server, and CRUD (Create-Read-Update-Delete).

Step-by-Step.

Let's get started.

 

#1. What is React JS

React is a javascript library for building the user interface (UI) of an application or website.

React runs on the client side as a Single Page Application (SPA).

React is often compared to front-end javascript frameworks like Angular and Vue JS.

Why use React JS.?

- React Very Fast and Lightweight.

- React is also very popular and maintained by facebook

- Using JSX Syntax

- Using Virtual DOM (Document Object Model)

 

#2. Create React App

There are many ways to create a React js project. However, the easiest way is "create react app".

To be able to run the command “create-react-app”, you just need to install node.js on your computer.

You can download node.js at the following link and install it on your computer:

https://nodejs.org/en/

After node.js is installed on your computer, open Command Prompt or terminal then type the following command to make sure node.js is installed properly on your computer:

node -v

Then type the following command to make sure NPM (Node Package Manager) is also installed properly:

npm -v

Look at the following picture for more details:

node version

After node.js and npm are installed properly on your computer, create a new react project by typing the following command in the command prompt or terminal:

npx create-react-app my-react-app

Like the following picture:

create-react-app

The above command will create a new React project named “my-react-app”.

As seen in the image above, I created a React project in the "Tutorials" folder in "Documents".

If you don't have the folder, please create it first, then cd (change directory) to the folder as shown above.

When the installation is complete, cd to “my-react-app” folder.

Like the following picture:

react project

Then open the react project using the code editor, here I am using Visual Studio Code.

I also recommend that you use Visual Studio Code.

You just need to type the following command to open “my-react-app” project using Visual Studio Code:

code .

After the project is opened using Visual Studio Code, open a terminal in VS Code, then type the following command in the terminal to run the project:

npm start

If it goes well, it will look like the following image:

npm start

Then open your browser and visit the following URL:

http://localhost:3000

Then it will appear as follows:

react

 

#3. Folder Structure

If you look in more detail, then you will get a folder structure like the following:

folder

In the picture above, there are 3 folders, namely: node_modules, public, and src folders.

The node_modules folder contains all the modules needed to create the project.

The public folder contains the index.html, favicon.ico, and several other files.

The index.html file represents a Single Page Application (SPA).

The src folder contains the files App.css, App.js, App.test.js, index.css, index.js, logo.svg, reportWebVitals.js, and setupTests.js.

What's important for you to know is the App.js and index.js files.

The App.js file is the root component file of react app, while the index.js file is the entry point of our application.

Next, do a little clean up. Delete the App.css, App.test.js, index.css, logo.svg, reportWebVitals.js, and setupTests.js files.

So that what remains is only the App.js and index.js files.

Like the following picture:

project folder

Then open the App.js file, change the code to be like this:

function App() {
  return (
    <div>
      <h2>Hello World</h2>
    </div>
  );
}

export default App;

After that open the index.js file, change the code to be like this:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Back to the browser, if it runs well, it will look like the following image:

hello world

 

#4. Components

One of the important concepts you need to know in React JS is components.

React is a Single Page Application (SPA) which has multiple components.

For example, create a “components” folder in the “src” folder.

Then create a components file named “Header.js” in that folder.

Look at the following picture for more details:

header components

Then type the following code in the components file “Header.js”:

const Header = () => {
    return (
        <div>
            <h2>This is Header Component</h2>
        </div>
    )
}

export default Header

Next, open the "App.js" file, then change the code to be like this:

import Header from "./components/Header";

function App() {
  return (
    <div>
      <Header />
    </div>
  );
}

export default App;

Back to the browser, if it went well, it will look like the following:

header components

 

#5. Click Events

We can call methods using click events.

For example, change the code "App.js" to be like this:

import Header from "./components/Header";

function App() {

  const clickMe = () => {
    console.log('Clicked');
  }

  return (
    <div>
      <Header />
      <button onClick={ clickMe }>Click Me</button>
    </div>
  );
}

export default App;

Go back to the browser, inspect the element => console => then click the “Click Me” button.

If it goes well, it will look like the following image:

click events

In addition, we can also pass parameters.

For example, change the code "App.js" to be like this:

import Header from "./components/Header";

function App() {

  const clickMe = (name) => {
    console.log('Hello: '+ name);
  }

  return (
    <div>
      <Header />
      <button onClick={ () => clickMe('Fikri') }>Click Me</button>
    </div>
  );
}

export default App;

Return to the browser, then click the "Click Me" button.

If it goes well, it will look like the following image:

events

 

#6. useState Hook

The useState hook allows us to define a state, define an initial value in the state, and update the value of a state.

For example, change the code "App.js" to be like this:

import { useState } from "react"

function App() {
  const [title, setTitle] = useState("Hello World");

  const changeTitle = () => {
    setTitle("Title Changed");
  }

  return (
    <div>
      <h1>{ title }</h1>
      <button onClick={ changeTitle }>Change Title</button>
    </div>
  );
}

export default App;

Return to the browser, it will look like the following image:

usestate

Click the "Change Title" button, then the title will change as follows:

usestate

 

#7. Looping Lists

We can output list data in react by using map function in javascript.

For example, change the code "App.js" to be like this:

import { useState } from "react"

function App() {
  const [products, setProducts] = useState([
    {id: 1, title: 'Product 1', price: 899},
    {id: 2, title: 'Product 2', price: 982},
    {id: 3, title: 'Product 3', price: 322},
    {id: 4, title: 'Product 4', price: 763},
    {id: 5, title: 'Product 5', price: 389}
  ]);

  return (
    <div>
      <ul>
        {products.map((product) => (
          <li key={ product.id }> { product.title } - { product.price } </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Return to the browser, it will look like the following image:

lists

 

#8. Props

Props is one way to send data from parent components to child components.

For example, create a components file named “ProductList.js” in the “src/components” folder.

Then type the following code:

const ProductList = ({ products }) => {
    return (
        <div>
            <ul>
                {products.map((product) => (
                <li key={ product.id }> { product.title } - { product.price } </li>
                ))}
            </ul>
        </div>
    )
}

export default ProductList

After that, change the code "App.js" to be like this:

import { useState } from "react"
import ProductList from "./components/ProductList";

function App() {
  const [products, setProducts] = useState([
    {id: 1, title: 'Product 1', price: 899},
    {id: 2, title: 'Product 2', price: 982},
    {id: 3, title: 'Product 3', price: 322},
    {id: 4, title: 'Product 4', price: 763},
    {id: 5, title: 'Product 5', price: 389}
  ]);

  return (
    <div>
      <ProductList products={ products } />
    </div>
  );
}

export default App;

Back to the browser, if it runs well, then it still appears as before.

In addition, we can also use props as a function to send data from child components to parent components.

For more details, change the code in the "ProductList.js" component to be as follows:

const ProductList = ({ products, deleteProduct }) => {
    return (
        <div>
            <ul>
                {products.map((product) => (
                <li key={ product.id }> { product.title } - { product.price } 
                    <button onClick={ () => deleteProduct(product.id) }>Delete</button>
                </li>
                ))}
            </ul>
        </div>
    )
}

export default ProductList

Then change the code "App.js" to be like this:

import { useState } from "react"
import ProductList from "./components/ProductList";

function App() {
  const [products, setProducts] = useState([
    {id: 1, title: 'Product 1', price: 899},
    {id: 2, title: 'Product 2', price: 982},
    {id: 3, title: 'Product 3', price: 322},
    {id: 4, title: 'Product 4', price: 763},
    {id: 5, title: 'Product 5', price: 389}
  ]);

  const deleteProduct = (productId) => {
    const newProducts = products.filter(product => product.id !== productId);
    setProducts(newProducts);
  }

  return (
    <div>
      <ProductList products={ products } deleteProduct={ deleteProduct } />
    </div>
  );
}

export default App;

Go back to the browser, it will look like the following:

props

Then click one of the "Delete" buttons then the product list will be deleted based on "id", where "id" comes from the child component, namely "ProductList.js".

 

#9. useEffect Hook

useEffect is a function that runs every time there is a change in the DOM.

For more details, change the code "App.js" to be like this:

import { useState, useEffect } from "react"
import ProductList from "./components/ProductList";

function App() {
  const [products, setProducts] = useState([
    {id: 1, title: 'Product 1', price: 899},
    {id: 2, title: 'Product 2', price: 982},
    {id: 3, title: 'Product 3', price: 322},
    {id: 4, title: 'Product 4', price: 763},
    {id: 5, title: 'Product 5', price: 389}
  ]);

  const deleteProduct = (productId) => {
    const newProducts = products.filter(product => product.id !== productId);
    setProducts(newProducts);
  }

  useEffect(() => {
    console.log('Use Effect Running');
  });

  return (
    <div>
      <ProductList products={ products } deleteProduct={ deleteProduct } />
    </div>
  );
}

export default App;

Go back to the browser, then open the console.

The first time the page loads, useEffect runs. Then click one of the "Delete" buttons, then useEffect is running again.

Like the following picture:

useEffect

In addition, we can also call useEffect only when the page loads.

For example, change the useEffect function in “App.js” to be like this:

useEffect(() => {
  console.log('Use Effect Running');
}, []);

In addition, we can also call useEffect depending on the change of a state.

For example, change the code "App.js" to be like this:

import { useState, useEffect } from "react"
import ProductList from "./components/ProductList";

function App() {
  const [products, setProducts] = useState([
    {id: 1, title: 'Product 1', price: 899},
    {id: 2, title: 'Product 2', price: 982},
    {id: 3, title: 'Product 3', price: 322},
    {id: 4, title: 'Product 4', price: 763},
    {id: 5, title: 'Product 5', price: 389}
  ]);

  const [name, setName] = useState('Fikri');

  const deleteProduct = (productId) => {
    const newProducts = products.filter(product => product.id !== productId);
    setProducts(newProducts);
  }

  useEffect(() => {
    console.log('Use Effect Running');
  }, [name]);

  return (
    <div>
      <ProductList products={ products } deleteProduct={ deleteProduct } />
      <button onClick={ () => setName('John') }>Change Name</button>
      <p>Name: { name }</p>
    </div>
  );
}

export default App;

Back to Browser, then useEffect runs the first time the page loads.

Then click the "Change Name" button, then useEffect runs again.

If you click one of the “Delete” buttons, then useEffect will not run.

Like the following picture:

useEffect

 

#10. React Router

We can make our application like a multiple page application by using react router.

Unlike the usual multiple page application, react router does not make a request to the server, but only renders components on the client side with a certain URL.

To be able to use react router, we need to install react-router-dom.

Open a new terminal, then type the following command to install react-router-dom:

npm install react-router-dom

After the installation is complete, create a component file named “About.js” in the “src/components” folder.

Then type the following code:

const About = () => {
    return (
        <div>
            <h2>This is About Page</h2>
        </div>
    )
}

export default About

After that, create another component file named “Contact.js” in the “src/components” folder.

Then type the following code:

const Contact = () => {
    return (
        <div>
            <h2>This is Contact Page</h2>
        </div>
    )
}

export default Contact

Next, change the code "App.js" to be like this:

import { useState } from "react"
import ProductList from "./components/ProductList";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import About from "./components/About";
import Contact from "./components/Contact";

function App() {
  const [products, setProducts] = useState([
    {id: 1, title: 'Product 1', price: 899},
    {id: 2, title: 'Product 2', price: 982},
    {id: 3, title: 'Product 3', price: 322},
    {id: 4, title: 'Product 4', price: 763},
    {id: 5, title: 'Product 5', price: 389}
  ]);

  const deleteProduct = (productId) => {
    const newProducts = products.filter(product => product.id !== productId);
    setProducts(newProducts);
  }

  return (
    <div>
      <Router>
        <Switch>
          <Route exact path="/">
            <ProductList products={ products } deleteProduct={ deleteProduct } />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/contact">
            <Contact />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

export default App;

Go back to the browser, it will look like the following:

list

Visit the URL "/about", it will look like the following page about:

about

Visit the URL "/contact", it will look like the following contact page:

contact

 

#11. JSON Server

We can create fake API using JSON Server.

For clarity, create a file “db.json” in the project root, aligned with the node_modules, public, and src folders.

Then type the following data in the "db.json" file:

{
    "products":[
        {"id": 1, "title": "Product 1", "price": 899},
        {"id": 2, "title": "Product 2", "price": 982},
        {"id": 3, "title": "Product 3", "price": 322},
        {"id": 4, "title": "Product 4", "price": 763},
        {"id": 5, "title": "Product 5", "price": 389}
    ]
}

After that, open a new terminal and run the following command:

npx json-server --watch db.json --port 8080

Go back to the browser and visit the following URL:

http://localhost:8080/products

If it goes well, it will look like the following image:

json server

 

#12. CRUD (Create-Read-Update-Delete)

In this tutorial, I'll be using Bulma CSS to style.

You can install Bulma CSS by typing the following command in a new terminal:

npm install bulma

After the bulma installation is complete, go to the “index.js” file, then add import bulma as follows:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "bulma/css/bulma.css";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Then change the code in the "ProductList.js" components file contained in the "src/components" folder to be as follows:

import { useState, useEffect } from "react";
import { Link } from "react-router-dom";

const ProductList = () => {
    const [products, setProducts] = useState([]);

    useEffect(() => {
        fetchData();
    }, []);

    const fetchData = async() => {
        const response = await fetch('http://localhost:8080/products');
        const data = await response.json();
        setProducts(data);
    }

    const deleteProduct = async(id) => {
        await fetch(`http://localhost:8080/products/${id}`,{
            method: "DELETE",
            headers:{
                'Content-Type': 'application/json'
            }
        });
        fetchData();
    }

    return (
        <div>
            <Link to="/add" className="button is-primary mt-5">Add New</Link>
            <table className="table is-striped is-fullwidth">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>Title</th>
                        <th>Price</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {products.map((product, index) => (
                        <tr key={product.id}>
                            <td>{ index + 1 }</td>
                            <td>{ product.title }</td>
                            <td>{ product.price }</td>
                            <td>
                                <Link to={`/edit/${product.id}`} className="button is-small is-info">Edit</Link>
                                <button onClick={() => deleteProduct(product.id)} className="button is-small is-danger">Delete</button>
                            </td>
                        </tr>
                    ))}
                    

                </tbody>
            </table>
        </div>
    )
}

export default ProductList

After that create a new components file named "AddProduct.js" in the "src/components" folder, then type the following code:

import { useState } from "react";
import { useHistory } from "react-router-dom";

const AddProduct = () => {
    const [title, setTitle] = useState('');
    const [price, setPrice] = useState('');
    const history = useHistory();

    const saveProduct = async(e) => {
        e.preventDefault();
        const product = { title, price };
        await fetch('http://localhost:8080/products',{
            method: "POST",
            body: JSON.stringify(product),
            headers:{
                'Content-Type': 'application/json'
            }
        });
        history.push("/");
    }

    return (
        <div>
            <form onSubmit={saveProduct}>
                <div className="field">
                <label className="label">Title</label>
                <div className="control">
                    <input className="input" value={title} onChange={(e) => setTitle(e.target.value)} type="text" placeholder="Title" />
                </div>
                </div>

                <div className="field">
                <label className="label">Price</label>
                <div className="control">
                    <input className="input" value={price} onChange={(e) => setPrice(e.target.value)} type="text" placeholder="Price" />
                </div>
                </div>
        
                <div className="field">
                <div className="control">
                    <button className="button is-primary">Save</button>
                </div>
                </div>
            </form>
        </div>
    )
}

export default AddProduct

After that, create a new components file again named “EditProduct.js” in the “src/components” folder, then type the following code:

import { useState, useEffect } from "react";
import { useHistory, useParams } from "react-router-dom";

const EditProduct = () => {
    const [title, setTitle] = useState('');
    const [price, setPrice] = useState('');
    const history = useHistory();
    const { id } = useParams();

    useEffect(() => {
        getProductById();
    }, []);

    const getProductById = async() => {
        const response = await fetch(`http://localhost:8080/products/${id}`);
        const data = await response.json();
        setTitle(data.title);
        setPrice(data.price);
    }

    const updateProduct = async(e) => {
        e.preventDefault();
        const product = { title, price };
        await fetch(`http://localhost:8080/products/${id}`,{
            method: "PUT",
            body: JSON.stringify(product),
            headers:{
                'Content-Type': 'application/json'
            }
        });
        history.push("/");
    }

    return (
        <div>
            <form onSubmit={updateProduct}>
                <div className="field">
                <label className="label">Title</label>
                <div className="control">
                    <input className="input" value={title} onChange={(e) => setTitle(e.target.value)} type="text" placeholder="Title" />
                </div>
                </div>

                <div className="field">
                <label className="label">Price</label>
                <div className="control">
                    <input className="input" value={price} onChange={(e) => setPrice(e.target.value)} type="text" placeholder="Price" />
                </div>
                </div>
        
                <div className="field">
                <div className="control">
                    <button className="button is-primary">Update</button>
                </div>
                </div>
            </form>
        </div>
    )
}

export default EditProduct

Then change the code in the "App.js" file to be like this:

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import ProductList from "./components/ProductList";
import AddProduct from "./components/AddProduct";
import EditProduct from "./components/EditProduct";

function App() {
  return (
    <div className="container">
      <div className="columns">
        <div className="column is-half is-offset-one-quarter">
          <Router>
            <Switch>
              <Route exact path="/">
                <ProductList />
              </Route>
              <Route path="/add">
                <AddProduct />
              </Route>
              <Route path="/edit/:id">
                <EditProduct />
              </Route>
            </Switch>
          </Router>
        </div>
      </div>
    </div>
  );
}

export default App;

Return to the browser, it will look like the following image:

product lists

Click the "Add New" button, an add new product form will appear as follows:

add product

Enter “Title” and “Price”, then click the “Save” button.

If it goes well, you will see the addition of data as follows:

product added

To update data, click one of the "Edit" buttons, a product edit form will appear as follows:

edit product

Change the “Title” and “Price”, then click the “Update” button.

If it goes well, the data changes will look like the following:

product updated

To delete data, click one of the "Delete" buttons, it will be deleted from the list.

 

Conclusion:

The discussion this time is about the React js tutorial for beginners.

Starting from what react is, why use react, create-react-app, components, click events, useState Hook, looping lists, props, useEffect Hook, React Router, JSON Server, and CRUD (Create-Read-Update-Delete).

So what are you waiting for, let's coding!

Download Source Code

Share:



Sponsorship:


Recommended for you


Comments (0)

Leave a Comment