You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历对象设置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

问题分析

  1. 多余的状态更新:setCity(city)完全没必要,city已经是当前状态值,调用它会触发无意义的重渲染
  2. 错误使用数组方法:filter是用来筛选符合条件的所有元素并返回新数组,用它查找单个元素逻辑错误,且回调返回的siti或"notfound"不是布尔值,不符合filter的要求
  3. 状态更新无返回值:setSelectedCity的回调函数里没有返回结果,导致状态无法被正确设置
  4. 边界情况未处理:当city为空字符串时,没必要执行查找逻辑
  5. 状态未暴露到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:07:11