在迭代对象以设置状态时出现问题。

huangapple go评论59阅读模式
英文:

Trouble in iterating an object to set state

问题

以下是翻译好的部分:

  • 尝试做的事情是
  • 获取输入并存储在城市状态中
  • 遍历名为citylist的对象,如果它存在于citylist中,则将selectedCity设置为该城市,否则返回未找到
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(() => {
				return cityList.cities.filter((cityItem) => (cityItem.name === city ? cityItem : '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
英文:

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 &#39;react&#39;
import { cityList } from &#39;../data/sample-data.js&#39;
import axios from &#39;axios&#39;

const WeatherContext = createContext()

export const WeatherContextProvider = ({ children }) =&gt; {
	const [city, setCity] = useState(&#39;&#39;)
	const [selected, setSelectedCity] = useState()

	useEffect(() =&gt; {
		const timer = setTimeout(() =&gt; {
			setCity(city)
			setSelectedCity(() =&gt; {
				cityList.cities.filter((siti) =&gt; (siti.name === city ? siti : &#39;notfound&#39;))
			})
			// console.log(selected)
		}, 500)

		return () =&gt; {
			clearTimeout(timer)
		}
	}, [city])

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

	return (
		&lt;WeatherContext.Provider
			value={{
				city,
				setCity,
				cityList,
				// fetchData
			}}&gt;
			{children}
		&lt;/WeatherContext.Provider&gt;
	)
}

export default WeatherContext

答案1

得分: 1

不需要在useEffect内调用setCity(city),因为当您输入时已经在设置city状态。如果使用相同的值调用setCity,将触发无限重新渲染,如果该城市是引用类型变量。

并且您正在使用filter来查找所选城市,但filter返回一个数组,而不是单个值。如果要找到第一个匹配的城市,您应该使用find而不是filter

例如:

useEffect(() => {
  const timer = setTimeout(() => {
    const matchedCity = cityList.cities.find((cityItem) => cityItem.name === city);
    setSelectedCity(matchedCity ? matchedCity : "notfound");
  }, 500);

  return () => {
    clearTimeout(timer);
  };
}, [city]);
英文:

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(() =&gt; {
const timer = setTimeout(() =&gt; {
const matchedCity = cityList.cities.find((siti) =&gt; siti.name === city);
setSelectedCity(matchedCity ? matchedCity : &quot;notfound&quot;);
}, 500);
return () =&gt; {
clearTimeout(timer);
};
}, [city]);

答案2

得分: 0

这应该会导致无限循环。

其次,您的筛选函数没有正确编写。应该如下所示:

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

请记住这不是一个映射函数。您需要返回真值或假值以指示元素是否应存在于筛选后的数组中。在您的情况下,您根本没有进行筛选。您需要一个单一的结果,但您正在设置整个数组。

希望这有所帮助。请务必处理基础知识。

英文:

What are you trying to do here

useEffect(() =&gt; {
const timer = setTimeout(() =&gt; {
setCity(city) // &lt;---
setSelectedCity(() =&gt; {
cityList.cities.filter((siti) =&gt; (siti.name === city ? siti : &#39;notfound&#39;))
})
// console.log(selected)
}, 500)
return () =&gt; {
clearTimeout(timer)
}
}, [city])  // &lt;---

This should be causing infinite loop.

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

cityList.cities.filter(city1 =&gt; city1.name === city)[0] || &#39;notfound&#39;

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

huangapple
  • 本文由 发表于 2023年7月20日 17:18:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76728394.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定