How to develop a Vite+ React Project

Rashmi Mishra
0

How to develop a Vite+ React Project

To develop a project using Vite and React, follow these steps:

Prerequisites:

Node.js and npm installed on your machine.

Step 1: Install Vite

Open your terminal.

Run the following command to create a new Vite project:

npm create vite@latest



Choose your project name, for example: my-vite-react-app.



When prompted, select React as the framework and JavaScript or TypeScript (based on your preference) as the language.





Step 2: Navigate to the Project Directory

Once the project is created, navigate to your new project folder:

cd my-vite-react-app



Step 3: Install Dependencies

Install the necessary dependencies:

npm install   

or 

npm i



Step 4: Start the Development Server

Run the development server with Vite:

npm run dev

This will start the development server and give you the URL (usually http://localhost:5173) to view your app in the browser.



Output on browser:



Step 5: Project Structure Overview

Your project will have the following structure:

my-vite-react-app/

├── node_modules/

├── public/

│   └── index.html

├── src/

│   ├── assets/

│   ├── App.jsx (or App.tsx if using TypeScript)

│   ├── main.jsx (or main.tsx if using TypeScript)

│   └── ...

├── index.html

└── vite.config.js

public/index.html: Main HTML file.

src/main.jsx: Entry point for the React application.

src/App.jsx: Main component.

Step 6: Add Components and Routes

You can now start building your React components inside the src/ folder.

First you create a folder in src folder , named that as component and inside component folder u have to create all component required for your project.

For example, you could create a new component Hello.jsx :

Hello.jsx


// src/components/Hello.jsx

function Hello() {

  return <h1>Hello, Vite + React!</h1>;

}

export default Hello;

 

 App.jsx

Modify the App.jsx  And import Hello.jsx into App.jsx:

// src/App.jsx

import Hello from './components/Hello';

function App() {

  return (

    <div>

      <Hello />

    </div>

  );

}

export default App;

 

 

Step 7: Build the Project for Production

Once you're done developing, you can build your project for production:

npm run build





The production-ready files will be placed in the dist folder, which can be deployed to any static hosting provider.


Step 8: Preview the Production Build

You can preview the production build locally:

npm run preview



Optional Step: 

Adding Libraries

You can add other libraries such as React Router, Redux, etc. via npm:

npm install react-router-dom

Then use them as you would in any React project.


Example (Vite + React Project)

Weather App


To create a weather app using React and Vite, follow these steps:

Step 1: Install Node.js and npm

Ensure you have Node.js installed on your machine. If not, download and install it from Node.js official website.

Step 2: Install Vite

Open your terminal and run:

npm create vite@latest

You'll be prompted to name your project. Enter a project name (e.g., weather-app).

Choose React as the framework.

Choose JavaScript as the variant (or TypeScript if you prefer).

Step 3: Navigate to the Project Directory

Once Vite sets up the project, navigate to the project directory:

cd weather-app

Step 4: Install Dependencies

Run the following command to install the dependencies:

npm install

Step 5: Install Axios (for API Requests)

You will need a package to make HTTP requests to the weather API. Use Axios for this:

npm install axios

Step 6: Get API Key from OpenWeatherMap

Sign up at OpenWeatherMap.

Go to the API section and generate an API key (free tier available).

Step 7: Create the Weather Component

In the src folder, create a new folder called components and a file called Weather.jsx.The weather data is fetched using the native fetch API instead of a library like axios.


Using fetch(url):

src/components/Weather.jsx:

Code of Weather.jsx

import React, { useEffect, useState, useRef } from 'react'
import './Weather.css'
import search_icon from '../assets/search.png'
import clear_icon from '../assets/clear.png'
import cloud_icon from '../assets/cloud.png'
import drizzle_icon from '../assets/drizzle.png'
import humidity_icon from '../assets/humidity.png'
import rain_icon from '../assets/rain.png'
import snow_icon from '../assets/snow.png'
import wind_icon from '../assets/wind.png'

const Weather = () => {
    const inputRef = useRef()
    const [weatherData, setWeatherData] = useState(false);

    const allIcon ={
        "01d": clear_icon,
        "01n": clear_icon,
        "02d": cloud_icon,
        "02n": cloud_icon,
        "03d": cloud_icon,
        "03n": cloud_icon,
        "04d": drizzle_icon,
        "04n": drizzle_icon,
        "09d": rain_icon,
        "09n": rain_icon,
        "10d": rain_icon,
        "10n": rain_icon,
        "13d": snow_icon,
        "13n": snow_icon,
    }

    const search = async (city) => {
        if(city===""){
            alert("Enter city name");
            return;
        }
        try {
            const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${import.meta.env.VITE_APP_ID}`;

            const response = await fetch(url);
            const data = await response.json();

            if(!response.ok){
                alert(data.message);
                return;
            }


            console.log(data);
            const icon = allIcon[data.weather[0].icon] || clear_icon;
            setWeatherData({
                humidity: data.main.humidity,
                windSpeed: data.wind.speed,
                temperature: Math.floor(data.main.temp),
                location: data.name,
                icon: icon
            })
        } catch (error) {
            setWeatherData(false);
            console.error("Error in fetching weather data");
        }
    }
    useEffect(()=>{
        search("London");
    },[])
    return (
        <div className='weather'>
            <div className="search-bar">
                <input ref={inputRef} type="text" placeholder='Search' />
                <img src={search_icon} alt="" onClick={()=>search(inputRef.current.value)}/>
            </div>
            {weatherData?<>
                <img src={weatherData.icon} alt="" className='weather_icon' />
            <p className='temperature'>{weatherData.temperature}°c</p>
            <p className='location'>{weatherData.location}</p>
            <div className="weather-data">
                <div className="col">
                    <img src={humidity_icon} alt="" />
                    <div>
                        <p>{weatherData.humidity}%</p>
                        <span>Humidity</span>
                    </div>
                </div>
                <div className="col">
                    <img src={wind_icon} alt="" />
                    <div>
                        <p>{weatherData.windSpeed} km/h</p>
                        <span>Wind Speed</span>
                    </div>
                </div>
            </div>
            </>:<></>}
           
        </div>
    )
}

export default Weather

 

Explanation:

1. Imports

import React, { useEffect, useState, useRef } from 'react';

import './Weather.css';

import search_icon from '../assets/search.png';

import clear_icon from '../assets/clear.png';

import cloud_icon from '../assets/cloud.png';

import drizzle_icon from '../assets/drizzle.png';

import humidity_icon from '../assets/humidity.png';

import rain_icon from '../assets/rain.png';

import snow_icon from '../assets/snow.png';

import wind_icon from '../assets/wind.png';

This section imports the necessary libraries and assets:

React, along with its hooks: useEffect, useState, and useRef.

CSS for styling (Weather.css).

Various weather-related icons (e.g., clear_icon, cloud_icon, etc.) and other UI icons (search_icon).

2. Weather Component

const Weather = () => {

    const inputRef = useRef();

    const [weatherData, setWeatherData] = useState(false);

The Weather component is created as a functional component.

inputRef is initialized using the useRef hook. This will allow us to access the input field's value directly.

weatherData is a state variable (using useState) initialized to false. It will later hold the fetched weather data.

3. Icon Mapping Object

    const allIcon = {

        "01d": clear_icon,

        "01n": clear_icon,

        "02d": cloud_icon,

        "02n": cloud_icon,

        "03d": cloud_icon,

        "03n": cloud_icon,

        "04d": drizzle_icon,

        "04n": drizzle_icon,

        "09d": rain_icon,

        "09n": rain_icon,

        "10d": rain_icon,

        "10n": rain_icon,

        "13d": snow_icon,

        "13n": snow_icon,

    };

The allIcon object maps the weather codes (provided by the OpenWeather API) to corresponding icon files.

For example, "01d" (clear sky during the day) maps to clear_icon, while "09d" (rain during the day) maps to rain_icon.

4. Search Function

    const search = async (city) => {

        if(city === "") {

            alert("Enter city name");

            return;

        }

        try {

            const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${import.meta.env.VITE_APP_ID}`;

            const response = await fetch(url);

            const data = await response.json();


            if(!response.ok) {

                alert(data.message);

                return;

            }


            const icon = allIcon[data.weather[0].icon] || clear_icon;

            setWeatherData({

                humidity: data.main.humidity,

                windSpeed: data.wind.speed,

                temperature: Math.floor(data.main.temp),

                location: data.name,

                icon: icon

            });

        } catch (error) {

            setWeatherData(false);

            console.error("Error in fetching weather data");

        }

    };

Purpose: This asynchronous function fetches weather data from the OpenWeatherMap API based on the city parameter.

Logic:

If the city name is empty, an alert asks the user to enter a city name.

The fetch function sends a GET request to the OpenWeather API, passing the city name and your API key (appid=${import.meta.env.VITE_APP_ID}).

If the response is not OK (e.g., city not found), it alerts the user with the error message from the API.

If the response is successful, it maps the icon code to the appropriate weather icon.

It then sets the weatherData state with key information such as humidity, wind speed, temperature, location, and the corresponding weather icon.

Error Handling: If an error occurs (e.g., network issue), the weather data is reset to false, and an error message is logged to the console.

5. useEffect Hook

    useEffect(() => {

        search("London");

    }, []);

Purpose: When the Weather component first renders, the useEffect hook triggers the search function to fetch the weather data for London by default.

The empty dependency array ([]) ensures this effect only runs once when the component mounts.

6. JSX (Render Output)

    return (

        <div className='weather'>

            <div className="search-bar">

                <input ref={inputRef} type="text" placeholder='Search' />

                <img src={search_icon} alt="" onClick={() => search(inputRef.current.value)} />

            </div>

            {weatherData ? (

                <>

                    <img src={weatherData.icon} alt="" className='weather_icon' />

                    <p className='temperature'>{weatherData.temperature}°c</p>

                    <p className='location'>{weatherData.location}</p>

                    <div className="weather-data">

                        <div className="col">

                            <img src={humidity_icon} alt="" />

                            <div>

                                <p>{weatherData.humidity}%</p>

                                <span>Humidity</span>

                            </div>

                        </div>

                        <div className="col">

                            <img src={wind_icon} alt="" />

                            <div>

                                <p>{weatherData.windSpeed} km/h</p>

                                <span>Wind Speed</span>

                            </div>

                        </div>

                    </div>

                </>

            ) : (

                <></>

            )}

        </div>

    );

Search Bar:

Contains an input field where users can type the name of the city.

The search button (represented by the search_icon) triggers the search function when clicked, using the value from the input field (inputRef.current.value).

Weather Data Display:

If weatherData exists (i.e., valid weather data was fetched), the component renders the weather information, including:

Weather icon (fetched from the icon field in weatherData).

Temperature and location (fetched from weatherData).

Humidity and wind speed (also fetched from weatherData), each with its corresponding icon.

Conditional Rendering:

If weatherData is false (e.g., no data or an error occurred), nothing will be rendered below the search bar.


Step 8: Step  for Styling:

Code of Weather.css

.weather{

    place-self: center;

    padding: 40px;

    border-radius: 10px;

    background-image: linear-gradient(45deg,#2f4680,#500ae4);

    display: flex;

    flex-direction: column;

    align-items: center;

}



.search-bar{

    display: flex;

    align-items: center;

    gap: 12px;



}



.search-bar input{

    height: 50px;

    border: none;

    outline: none;

    border-radius: 40px;

    padding-left: 25px;

    color: #626262;

    background: #ebfffc;

    font-size: 18px;

}



.search-bar img{

    width: 50px;

    padding: 15px;

    border-radius: 50%;

    background: #ebfffc;

    cursor: pointer;

}



.weather_icon{

    width: 150px;

    margin: 30px 0;

}



.temperature{

    color: #fff;

    font-size: 80px;

    line-height: 1;

}



.location{

    color: #fff;

    font-size: 40px;

}



.weather-data{

    width: 100%;

    margin-top: 40px;

    color: #fff;

    display: flex;

    justify-content: space-between;

}



.weather-data .col{

    display: flex;

    align-items: flex-start;

    gap: 12px;

    font-size: 22px;

}



.weather-data .col span{

    display: block;

    font-size: 16px;

}



.weather-data .col img{

    width: 26px;

    margin-top: 10px;

}

 

 

Step 9: Modify the App.jsx

Code of App.jsx(After Modification):


import React from "react";

import Weather from './components/Weather'

function App() {

  return (

    <>

    <div className="app">

        <Weather/>

    </div>

    </>

  );

}

 

export default App

 

Step 10: Modify the index.css

Code of index.css

@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;

0,200;

0,300;

0,400;

0,500;

0,600;

0,700;

0,800;

0,900;

1,100;

1,200;

1,300;

1,400;

1,500;

1,600;

1,700;

1,800;

1,900&display=swap');

*{

  margin: 0;

  padding: 0;

  box-sizing: border-box;

  font-family: "Poppins", sans-serif;

}

 

.app{

  min-height: 100vh;

  display: grid;

  background: #e2d4ff;

}

 

Step 11: Modify the main.jsx

Code of main.jsx:

import React from 'react'

import ReactDOM from 'react-dom/client'

import App from './App.jsx'

import './index.css'

 

ReactDOM.createRoot(document.getElementById('root')).render(

  <React.StrictMode>

    <App />

  </React.StrictMode>,

)

 

 

 

Step 12: Modify the index.html

Code of index.html

<!doctype html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <link rel="icon" type="image/svg+xml" href="/vite.svg" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>MyWeatherApp</title>

  </head>

  <body>

    <div id="root"></div>

    <script type="module" src="/src/main.jsx"></script>

  </body>

</html>

 

 

Step 13: Modify the App Component

In src/App.jsx, import and use the Weather component:

App.jsx:

import React from 'react';

import Weather from './components/Weather';

function App() {

  return (

    <div>

      <Weather />

    </div>

  );

}

 export default App;

 Step 9: Run the Application

Start the development server by running:

npm run dev

Open your browser and go to http://localhost:5173. You should see the weather app where you can enter a city name and get the weather data.


In a Vite + React project, you can use either .js or .jsx for React components. Both work, but .jsx is typically preferred for React components because it explicitly indicates the use of JSX syntax (HTML-like syntax inside JavaScript).

Using Axios:

You will need a package to make HTTP requests to the weather API. Use Axios for this:

Weather.jsx(src/components/Weather.jsx) :

import React, { useState, useEffect } from 'react';

import axios from 'axios';

const Weather = () => {

  const [weatherData, setWeatherData] = useState(null);

  const [city, setCity] = useState('');

  const [error, setError] = useState('');

 

  const fetchWeather = async () => {

    const apiKey = 'YOUR_API_KEY';

    const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`;

 

    try {

      const response = await axios.get(url);

      setWeatherData(response.data);

      setError('');

    } catch (error) {

      setError('City not found or network error');

      setWeatherData(null);

    }

  };

 

  const handleSubmit = (e) => {

    e.preventDefault();

    if (city) {

      fetchWeather();

    } else {

      setError('Please enter a city name');

    }

  };

 

  return (

    <div>

      <h1>Weather App</h1>

      <form onSubmit={handleSubmit}>

        <input

          type="text"

          placeholder="Enter city"

          value={city}

          onChange={(e) => setCity(e.target.value)}

        />

        <button type="submit">Get Weather</button>

      </form>

 

      {error && <p>{error}</p>}

 

      {weatherData && (

        <div>

          <h2>{weatherData.name}</h2>

          <p>{weatherData.weather[0].description}</p>

          <p>Temperature: {weatherData.main.temp}°C</p>

          <p>Humidity: {weatherData.main.humidity}%</p>

        </div>

      )}

    </div>

  );

};

export default Weather;

 

 

 Output:






 

 

 

Post a Comment

0Comments

Post a Comment (0)