'How can I 'not allow' the user to retrieve same information from the server multiple times in my 'React' Weather-app?

I'm learning React and as a practice I'm building a weather-app.

My App Photo

Everything is ok. but I want When a User type a City name for example 'London' and click the Search button and get the data . the next search if it's 'london' (which is currently visible) i don't want my handleGetData function to call server for data.

How should implement this logic ? What should i change? I will appreciate your help

import React, { Component } from "react";
import InputSearch from "./common/inputSearch";
import http from "../services/httpService";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import Weather from "./weather";

class App extends Component {
  state = {
    city: {
      name: "",
      info: [],
    },
  };

  handleChange = (e) => {
    const city = this.state.city;
    city.name = e.currentTarget.value;
    this.setState({ city });
  };

  handleGetData = async () => {
    try {
      const city = this.state.city;
      const apiEndPoint = `http://api.weatherapi.com/v1/forecast.json?key=97de37820e0e4a29b9c90051221604&q=${city.name}&days=3&aqi=no&alerts=no`;
      const { data } = await http.get(apiEndPoint);
      city.info = data;
      this.setState({ city });
    } catch (e) {
      const expectedError =
        e.response.status && e.response.status > 400 && e.response.status < 500;
      if (expectedError) {
        toast.error("Something failed while getting Data");
      }
    }
  };

  render() {
    const { city } = this.state;
    return (
      <React.Fragment>
        <ToastContainer />
        <InputSearch
          stateCityName={city.name}
          onChanges={this.handleChange}
          onGettingData={this.handleGetData}
        />
        <Weather data={city.info} data2={city} />
      </React.Fragment>
    );
  }
}

export default App;


Solution 1:[1]

You can use a new state as your previousSearch and compare it with your current search

It's something like this but I didn't test it though so you may have to do some modification

    state = {
        city: {
            name: "",
            info: [],
        },
        previousSearch: "",
    };

    handleChange = (e) => {
    const city = this.state.city;
    prevCity = city.name;
    city.name = e.currentTarget.value;
    this.setState({ city, previousSearch: prevCity });
    };

  handleGetData = async () => {
    try {
      const city = this.state.city;
      if(previousSearch !== city.name) {
        const apiEndPoint = `http://api.weatherapi.com/v1/forecast.json?key=97de37820e0e4a29b9c90051221604&q=${city.name}&days=3&aqi=no&alerts=no`;
        const { data } = await http.get(apiEndPoint);
        city.info = data;
        this.setState({ city });
      }

    } catch (e) {
      const expectedError =
        e.response.status && e.response.status > 400 && e.response.status < 500;
      if (expectedError) {
        toast.error("Something failed while getting Data");
      }
    }
  };

Have fun

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zWANG