0

I would like to ask some help. I am trying to send the whole input value as a whole to the fetch URL by passing it to useState variable. My own code seems work but every time I starting to type, the key is automatically passed to the useState variable then the app crashed since there is no city with just 1 letter. How to handle this? The thing I want is after I send enter key, that's the time the value of input will e send to useState variable.

const onChangeHandler = e =>{
  e.preventDefault();
  setSearchCity(e.target.value);
}

 useEffect(() => {
     fetch(`http://api.openweathermap.org/data/2.5/weather?q=${searchCity}&units=metric&appid=sampleAPIKEYhere`)
    .then((res) => res.json())
    .then((data) => {
<form>
  <input type="text" placeholder="Search a city" onChange={onChangeHandler}/>
</form>
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
kevthedevv
  • 39
  • 1
  • 9
  • Your snippet is incomplete. You are using useEffect that will act differently depending on the dependencies array. Either way, the value you change with setSearchCity changes on every key press, which means you probably are going to do a fetch every time. You need to debounce the calls or make it onBlur and not on change. – Valery Dec 14 '20 at 09:23
  • Check this out: https://stackoverflow.com/questions/42217121/how-to-start-search-only-when-user-stops-typing – Mohamed Wagih Dec 14 '20 at 09:29
  • Thanks fo rthe answers. and sorry for short snippet – kevthedevv Dec 14 '20 at 10:04
  • Hey Kev, if the answer was helpful could you mark it as correct? – Michael Parkadze Apr 19 '21 at 08:11

2 Answers2

1

I was not so sure of what you meant in your question, but I did see some issues that might cause the crash, here is the full version that should work for you:

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

export default function App() {
  const [searchCity, setSearchCity] = useState("");

  useEffect(() => {
    // If searchCity is 2 letters or more
    if (searchCity.length > 1) {
      fetch(
        `http://api.openweathermap.org/data/2.5/weather?q=${searchCity}&units=metric&appid=sampleAPIKEYhere`
      )
        .then((res) => res.json())
        .then((data) => {
          // Do what ever you want with data
        });
    }
  }, [searchCity]);

  const handleOnChange = (e) => {
    e.preventDefault()
    setSearchCity(e.target.value)
  }

  return <form>
    <input type="text" placeholder="Search a city" onChange={(e) => handleOnChange(e)}/>
  </form>;
}

Main things are the condition inside the useEffect and adding the searchCity state as a dependency so the useEffect will happen everytime the state changes, also I see you haven't passed the event parameter in your onChangeHandler so that might cause the issue as well.

Michael Parkadze
  • 445
  • 4
  • 11
0

It's answer is pretty simple just exchange onChange event handler with onClick event handler and pass the event with the value thats it, onChange : this event is raised when the text in a select, text, or textarea form item is altered by the user. onClick: this event is raised when the user clicks the user clicks on an object, for example: button, image, hyperlink, etc.