Skip to content
Related Articles

Related Articles

What are hooks and when we use them ?

View Discussion
Improve Article
Save Article
  • Last Updated : 03 Mar, 2022

Hooks are features that react provides us if we want to make functional components while creating a react web app. These features are alternatives to a few lifecycle methods like componentDidMount(), componentDidUpdate(), apart from this it gives us more flexibility to write maintainable code. One main reason to use hooks instead of class-based components is that understanding class-based components and working with them can be difficult or challenging when the complexity of the application increases.

In this article, we will learn about hooks in react and get you introduced to them.

Must know hooks:

  • React useState() hooks: This hook helps maintain a component state. It accepts a parameter called an initial state which is the default value of the component state. It returns two properties: the component state, and a function that we can use to update the component state. For example, in the code given below, we have destructured state and setState (we can name them anything not necessarily state and setState),

    const [state,setState] = useState({});
  • React useEffect() hooks: This hook accepts a function as the first argument and a dependency array as the second argument. This hook is similar to componentDidMount() and componentDidUpdate() i.e. the function will run whenever the component is first rendered and whenever the component’s state is updated. In order to run the argument function only once (when the component is rendered), we have to make the dependency array empty. But if we want the function to be rendered whenever a certain object or property or variable changes then we need to pass it to the dependency array. Also since it is an array we can pass more than one value. In the code given below consider there is a changeable variable input. Here the anonymous function will print ” welcome to geeks for geeks ” in the console whenever the input variable changes.

    useEffect(() => {
        console.log("welcome to geeks for geeks");
    }, [input])
  • React useRef() hooks: This hook helps us do mainly two things: Track input or state changes, and Get a reference of DOM nodes. It returns an object which has a current property and it holds the value which we want to keep a track of. In the code below we use useRef to access DOM node (input) later on in some code.

    const stateRef = useRef();
    // some code ...
    <input ref={stateRef} type='text' />

Now we will do a small project in order to understand how they work together in a react application.

Creating React Application:

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

npx create-react-app foldername

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

cd foldername

Step 3: Install Axios as a dependency.

npm install axios

Step 4: Run the development server.

npm start

Project structure: 

Implementation: Write down the following code in respective files.

App.js: In this component we will make use of useState() and useRef() hooks. With the help of useState() we will make a component state which will be the city or place the user wants to find the weather information. We have added basic styles, set up an anonymous onChange function for the input field which will update the value of inputRef.current, a handleClick() function which is responsible for updating the state whenever the user clicks on the button. Here we have set the default value of inputRef to be null. Also, note we have passed the state of the App component to the WeatherDataComponent() by the property name of the location.

App.js




import "./App.css";
import { useState, useRef } from "react";
import WeatherData from "./Components/WeatherComponent";
  
function App() {
    const [state, setstate] = useState("");
    const inputRef = useRef(null);
  
    const handleClick = () => {
        setstate(inputRef.current);
    };
  
    return (
        <div
            className="App"
            style={{
                display: "flex",
                justifyContent: "center",
                alignItems: "center",
                flexDirection: "column",
                margin: "1rem",
            }}
        >
            <div>
                <input
                    type="text"
                    onChange={(e) => (inputRef.current = 
                        e.target.value)}
                    style={{
                        outline: "none",
                        border: "none",
                        borderBottom: "1px solid 
                            rgb(110, 204, 113)",
                        margin: ".5rem",
                    }}
                    placeholder="Enter City"
                />
                <button
                    onClick={handleClick}
                    style={{
                        outline: "none",
                        border: "none",
                        backgroundColor: 
                            "rgb(110, 204, 113)",
                        padding: "8px",
                        borderRadius: "5px",
                        width: "60px",
                        cursor: "pointer",
                    }}
                >
                    Find
                </button>
            </div>
            <WeatherData location={state} />
        </div>
    );
}
  
export default App;


WeatherComponent.js: In this component we have used useEffect() hook and useState(). Here the component state is the weather data object that we are fetching from the RapidAPI you can see the details in the options object. We have added some basic styles to this component. Now we’ve made a state of the weatherData object, its mutating function, and initialized it to null by useState() hook. Whereas we’ve passed an anonymous function in useEffect() which in turn first defines an asynchronous fetchData function and then calls it. Also, note we can’t make the argument function of useEffect asynchronous so that’s why we defined a separate function to fetch data from the API. First, we have just put edge case’s checks that if the location is undefined or null or length is 0 then by default the location’s value should be Delhi. After the data is fetched with the help of the setWeatherData function we update the component state to be the weather data object of the user inputted city name. Also, note that there is an element in the dependency array because we don’t want the useEffect to run only once but rather to run whenever the location prop changes which is being passed from the parent component.

WeatherComponent.js




import React, { useState, useEffect } from "react";
import axios from "axios";
  
const WeatherComponent = ({ location }) => {
  const [weatherData, setWeatherData] = useState(null);
  
  useEffect(() => {
    const fetchData = async () => {
      if (location === undefined || location === null || location.length === 0)
        location = "Delhi";
  
      var options = {
        method: "GET",
        params: { q: location, days: "2" },
        headers: {
          "x-rapidapi-host": "weatherapi-com.p.rapidapi.com",
          "x-rapidapi-key":
            "ffc2438edbmsh0a88b634e6e77a7p123125jsnfb163d4d72f7",
        },
      };
      const response = await axios.request(options);
      console.log("response.data", response.data);
      setWeatherData(response.data);
    };
    fetchData();
  }, [location]);
  
  let displayData = "Loading...";
  if (weatherData !== null && weatherData !== undefined) {
    displayData = (
      <div
        style={{
          width: "40vw",
          padding: "15px",
          border: "2px solid rgb(110, 204, 113)",
          borderRadius: "8px",
        }}
      >
        <h3>Weather Info</h3>
        <h4> Region: {weatherData.location.region} </h4>
        <div style={{ display: "flex"
                      justifyContent: "space-between" }}>
          <p style={{ display: "inline" }}>
            Whether:
            {weatherData.forecast.forecastday[0].day.condition.text}
          </p>
  
          <p style={{ display: "inline" }}>
            Date:
            {weatherData.forecast.forecastday[0].date}{" "}
          </p>
  
        </div>
        <div style={{ display: "flex",
                      justifyContent: "space-between" }}>
          <p style={{ display: "inline" }}>
            Whether:
            {weatherData.forecast.forecastday[1].day.condition.text}
          </p>
  
          <p style={{ display: "inline" }}>
            Date:
            {weatherData.forecast.forecastday[1].date}{" "}
          </p>
  
        </div>
      </div>
    );
  }
  
  return <>{displayData}</>;
};
  
export default WeatherComponent;


Output: The output will look like this.

Explanation: In this react application we have used the above stated three hooks and their simultaneous working. First, the user will land into the application by default the weather data related to Delhi will be fetched and the state of the WeatherData component will get updated to the object of Delhi’s weather data. If the user enters any city’s name on the input and clicks the button the state of the App component will get updated to the input’s value and will get passed to the WeatherData component as a location prop. Then because of the dependency array, the useEffect’s function will run again and fetch weather data for the specified location thereby updating the state of the WeatherComponent.

Output:

a working demo of the app


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!