Open In App

How to update layouts based on viewport dimension using useViewport hook ?

The useViewport hook in React empowers developers to create responsive web applications by effortlessly accessing and responding to changes in viewport dimensions for diverse screen sizes and devices in today’s digital landscape.

Prerequisites:

What is the useViewport hook:

Syntax:



const {vw,vh} = useViewport(); 

Parameters:

They are units of measurement used in CSS to describe the size of elements relative to the viewport size.



Steps to Create React Application And Installing Module:

Step 1: Create a React application using the following command:

npx create-react-app useviewport-example

Step 2: After creating your project folder i.e. example, move to it using the following command:

cd useviewport-example

Step 3: Step to include useViewport hook:

npm install react-viewport-hooks

Project Structure:

Project structure

The updated dependencies in package.json file will look like:

"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"react-viewport-hooks": "^1.5.0",
"web-vitals": "^2.1.4",
}

Example 1: Adjusting a grid layout to a list layout when the viewport becomes narrower. We will check if the viewport width is less than 768px. If it is, the layout variable is set to ‘list’. If not, the layout variable is set to ‘grid’. Then, we will render the div. Inside it, a ternary operator is used to check the layout variable, if it’s a grid, the component <GridLayout /> is rendered, otherwise <ListLayout /> is rendered.




import React from 'react';
import { useViewport } from 'react-viewport-hooks';
 
import './App.css';
 
 
const GridLayout = () => {
    return (
        <div className="grid-layout">
            <div className="grid-item">Grid-Item 1</div>
            <div className="grid-item">Grid-Item 2</div>
            <div className="grid-item">Grid-Item 3</div>
            <div className="grid-item">Grid-Item 4</div>
        </div>
    );
};
 
const ListLayout = () => {
    return (
        <ul className="list-layout">
            <li className="list-item">List-Item 1</li>
            <li className="list-item">List-Item 2</li>
            <li className="list-item">List-Item 3</li>
            <li className="list-item">List-Item 4</li>
        </ul>
    );
};
 
const App = () => {
 
    const { vw } = useViewport();
    console.log(vw);
 
    let layout = 'grid';
    if (vw < 768) {
        layout = 'list';
    }
    return (
        <div>
            {layout === 'grid' ?
                <GridLayout /> :
                <ListLayout />}
        </div>
    );
}
 
export default App;




.grid-layout {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-gap: 10px;
}
 
.grid-item {
    background-color: green;
    padding: 10px;
    text-align: center;
    color: white;
    font-weight: bold;
}
 
.list-layout {
    list-style-type: none;
    padding: 0;
}
 
.list-item {
    background-color: pink;
    padding: 10px;
    margin-bottom: 10px;
    text-align: center;
}

Step to run the application: Run the application by using the following command:

npm start

Output: By default, the React project will run on port 3000.

Output: Using the viewport hook to update layouts based on viewport dimensions.

Example 2: In this example, the useViewport hook returns the current width of the viewport. If the width is greater than 768, then a full navigation bar is displayed. If the width is less than or equal to 768, then a “Menu” button is displayed instead. When the “Menu” button is clicked, the state of menuOpen is updated using setMenuOpen, and the submenu is displayed if menuOpen is true.




import React, { useState } from 'react';
import { useViewport }
    from 'react-viewport-hooks';
import './App.css'
 
const Navbar = () => {
    const { vw } = useViewport();
    const [menuOpen, setMenuOpen] =
        useState(false);
 
    return (
        <nav>
            <ul>
                <li>Home</li>
                {vw > 768 ? (
                    <>
                        <li>About</li>
                        <li>Contact</li>
                    </>
                ) : (
                    <li
                        onClick={
                            () =>
                                setMenuOpen(!menuOpen)}>
                        Menu
                        {menuOpen && (
                            <ul>
                                <li>About</li>
                                <li>Contact</li>
                            </ul>
                        )}
                    </li>
                )}
            </ul>
        </nav>
    );
};
 
export default Navbar;




nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
}
 
ul {
    list-style: none;
    display: flex;
    margin: 0;
    padding: 0;
}
 
li {
    margin: 0 1rem;
}
 
ul ul {
    display: none;
    position: absolute;
    background-color: lightgray;
}
 
li:hover>ul {
    display: block;
}

Step to run the application: Run the application by using the following command:

npm start

Output: By default, the React project will run on port 3000

Output


Article Tags :