遍历对象设置React状态时遇到问题,请求技术支持
React城市匹配状态设置问题修复
需求与问题
我需要实现以下功能:
- 获取输入内容并存入
city状态 - 遍历
cityList对象,若输入的city存在于列表中,将selectedCity状态设为该城市对象;不存在则设为"notfound"
但在遍历设置状态的过程中遇到问题,原代码如下:
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
问题分析
- 多余的状态更新:
setCity(city)完全没必要,city已经是当前状态值,调用它会触发无意义的重渲染 - 错误使用数组方法:
filter是用来筛选符合条件的所有元素并返回新数组,用它查找单个元素逻辑错误,且回调返回的siti或"notfound"不是布尔值,不符合filter的要求 - 状态更新无返回值:
setSelectedCity的回调函数里没有返回结果,导致状态无法被正确设置 - 边界情况未处理:当
city为空字符串时,没必要执行查找逻辑 - 状态未暴露到Context:
selected状态没有加入Provider的value中,子组件无法访问
修正后的代码
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(() => { // 处理空输入的情况 if (!city.trim()) { setSelectedCity(null) return } // 用find查找第一个匹配的城市 const matchedCity = cityList.cities.find(siti => siti.name === city) // 设置状态:找到就存城市对象,否则存"notfound" setSelectedCity(matchedCity || "notfound") }, 500) return () => { clearTimeout(timer) } }, [city]) // async function fetchData(url) { // const response = await axios.get(url) // console.log(response) // } return ( <WeatherContext.Provider value={{ city, setCity, selected, // 将selected状态暴露给子组件 cityList, // fetchData }}> {children} </WeatherContext.Provider> ) } export default WeatherContext
关键修改说明
- 移除了无意义的
setCity(city)调用 - 使用
Array.find()替代filter,精准查找单个匹配的城市对象,找不到时返回undefined - 处理了空输入的边界情况,避免无效查找
- 正确设置
selected状态:找到城市就存对象,否则存"notfound" - 将
selected状态加入Context的value,让子组件能访问到匹配结果
内容的提问来源于stack exchange,提问作者Nikhil
相关产品推荐
相关产品推荐

