skip to Main Content

what i’m trying to do here is

  • take the input and store it in the city state
  • iterate through an object named citylist and set the selectedCity to the city if it exists in citylist else return not found

import { createContext, useState, useEffect } from 'react'
import { cityList } from '../data/sample-data.js'
import axios from 'axios'

const WeatherContext = createContext()

export const WeatherContextProvider = ({ children }) => {
    const [city, setCity] = useState('')
    const [selected, setSelectedCity] = useState()

    useEffect(() => {
        const timer = setTimeout(() => {
            setCity(city)
            setSelectedCity(() => {
                cityList.cities.filter((siti) => (siti.name === city ? siti : 'notfound'))
            })
            // console.log(selected)
        }, 500)

        return () => {
            clearTimeout(timer)
        }
    }, [city])

    // async function fetchData(url) {
    //  const response = await axios.get(url)
    //  console.log(response)
    // }

    return (
        <WeatherContext.Provider
            value={{
                city,
                setCity,
                cityList,
                // fetchData
            }}>
            {children}
        </WeatherContext.Provider>
    )
}

export default WeatherContext

2

Answers


  1. You don’t need to call setCity(city) inside the useEffect, because you are already setting the city state when you take the input. Calling setCity with the same value will trigger an infinite re-render in case that city is reference type variable.

    And you are using filter to find the selected city, but filter returns an array, not a single value. If you want to find the first matching city, you should use find instead of filter.

    For example:

    useEffect(() => {
      const timer = setTimeout(() => {
        const matchedCity = cityList.cities.find((siti) => siti.name === city);
        setSelectedCity(matchedCity ? matchedCity : "notfound");
      }, 500);
    
      return () => {
        clearTimeout(timer);
      };
    }, [city]);
    
    Login or Signup to reply.
  2. What are you trying to do here

    useEffect(() => {
            const timer = setTimeout(() => {
                setCity(city) // <---
                setSelectedCity(() => {
                    cityList.cities.filter((siti) => (siti.name === city ? siti : 'notfound'))
                })
                // console.log(selected)
            }, 500)
    
            return () => {
                clearTimeout(timer)
            }
        }, [city])  // <---
    

    This should be causing infinite loop.

    Secondly, your filter function is not properly written. It should be as follows

    cityList.cities.filter(city1 => city1.name === city)[0] || 'notfound'
    

    Remember it is not a map function. You need to return Truthy or Falsy value to indicate whether the element should exist in the filtered array. In your case you are not filtering at all. And you need a single result, but you are setting entire array.

    Hope this helps. Please work on the basics

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search