Sunday, 17 April 2022

Building a Progressive Web App with React 18


 When some websites get visited on a smartphone, the website prompts the user to install itself into the user’s device like an app. When “downloaded” into the user’s device, these websites have almost the same features a native mobile app would. They even have icons that can be viewed on the user’s home screen. When a website has been built in such a way, then we say the website is a Progressive Web App.

What is a Progressive Web App (PWA) and how does it work?

A progressive Web App is a website that can behave like a native app. This is possible due to the additional customizations done to the Web app or website, which gives these capabilities. Some features a PWA is capable of include push notifications, the ability to work on Android and IOS without much difference, a regular icon on the home screen of the user’s device like a standard app would, and the ability to work offline.

Here are some reasons why Progressive Web Apps are to be chosen or used by developers.

  • Lower Costs: Building a native mobile app or desktop app requires a budget for hiring a developer. But with PWAs, a mobile developer is not needed as a website can be converted straight away into a Progressive Web App,

  • Time Saved: A PWA saves time that would’ve been spent building a mobile app. The same codebase can be shared across multiple platforms and still look and feel good.

  • Lightweight: PWAs are lightweight, not heavy and bulky. This helps the web app have faster loading times and optimum memory utilization.

  • Cross-Platform: PWAs are cross-platform. They run in Android, IOS, Windows, and even MacOS, accessible with any device with a browser.

  • Fast Update: A Progressive Web App does not need an update to be installed for it separately on any platform it is on. It updates on its own since it technically is a website.

In this article, we will be building a simple note-taking app with React JS and then making it a Progressive Web App.

Creating the project

We will use React 18 (the latest version of React JS) to build this project. Remember, we need to have Node version 14.0.0 (or higher) and npm version 5.6 or more to use React 18.

1npx create-react-app notes

And then we have our react notes app load.

After it is installed, we will run:

1cd notes
2npm start

After this, we can also proceed to open our newly created react app on our favorite code editor,

Creating the Page

And now, we will create our homepage with contain our App component. In the index.js, we have:

1import React from "react";
2import App from "./App";
3import { createRoot } from "react-dom/client";
4const container = document.getElementById("root");
5const root = createRoot(container);
6
7root.render(<App />);

And in our App.js we have

1import React, { useState } from 'react';
2import './style.css';
3
4export default function App() {
5 return (
6 <div>
7 <h1>My Notes</h1>
8 <input type="text" />
9 <button>Save</button>
10 </div>
11 );
12}

And now we have this displayed on our page:

First version of the page

Creating the Notes Component

We will create a Notes component that will display any available notes. The component will be inside a folder, and the folder will be created inside the src folder and called components.

After that, we will create a file called Notes.js inside the components folder and create a simple function that loops through available data served in the props, creating different p elements.

Component file structure

Inside the Notes.js file, we have:

1import React from 'react';
2
3function Notes({ data }) {
4 return data.map((value) => <p>{value}</p>);
5}
6
7export default Notes;

This means that our Notes component will always take the parameter data. Now to import it into our App.js, we have:

1import React, { useState } from 'react';
2import Notes from './components/Notes';
3import './style.css';
4
5export default function App() {
6 return (
7 <div>
8 <h1>My Notes</h1>
9 <input type="text" />
10 <button>Save</button>
11 <Notes/>
12 </div>
13 );
14}

Remember, our Notes component needs parameter data. We will create states for the data that will update whenever the save button is clicked.

1import React, { useState } from 'react';
2import Notes from './components/Note';
3import './style.css';
4
5export default function App() {
6 let [list, setList] = useState([]);
7 let [newNote, setNewNote] = useState('');
8
9 function addNote() {
10 let addedNote = list.concat(newNote);
11 setList(addedNote);
12 setNewNote('');
13 }
14
15 function handleChange(e) {
16 setNewNote(e.target.value);
17 }
18
19 return (
20 <div>
21 <h1>My Notes</h1>
22 <input type="text" value={newNote} onChange={handleChange} />
23
24 <button onClick={addNote}>Save</button>
25 <Notes data={list} />
26 </div>
27 );
28}

And now, we should be able to save some notes with our app.

The app, working

Registering our Service Worker

What is a service worker? A service worker is just a required JS program for our app to be a Progressive Web App.

So, to use a service worker, we will have to register it on our index.js, so we import serviceWorker.js into our index.js.

index.js:

1import React from "react";
2import App from "./App";
3import * as serviceWorker from "./serviceWorker"
4import { createRoot } from 'react-dom/client';
5const container = document.getElementById('root');
6const root = createRoot(container);
7
8root.render(<App/>);
9
10serviceWorker.register():

Editing our manifest.json file

The final step to making our app a PWA is to change some things in our manifest.json file. We will set our icons and other options available.

1{
2 "short_name": "My Notes App",
3 "name": "Notes Progressive Web Application",
4 "icons": [
5 {
6 "src": "icon.png",
7 "sizes": "192x192",
8 "type": "image/png"
9 },
10 {
11 "src": "icon.png",
12 "sizes": "512x512",
13 "type": "image/png"
14 }
15 ],
16 "start_url": "./",
17 "display": "standalone",
18 "theme_color": "#000000",
19 "background_color": "#ffffff"
20}

And finally, we have a PWA app working that can run on any device like a native app.


No comments: