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

React useState定义的房源对象中如何正确更新嵌套location属性

问题1:本地状态初始化逻辑存在时序问题

你在useEffect中先触发异步拉取房源的getListing方法,同步就执行了setEditListing(listing),此时异步请求尚未返回,redux中取出的listing还是初始空值,当前表单能填充默认值只是偶现的时序巧合,后续极大概率出现默认值丢失问题。
修正后的初始化代码:

const listing = useSelector((state) => state.listings.listing);
const [editListing, setEditListing] = React.useState({});

// 组件挂载时触发拉取房源数据
React.useEffect(() => {
    getListing(listingId)(dispatch);
}, [listingId, dispatch]);

// 监听redux中房源数据变化,拿到有效数据后再同步到本地编辑状态
React.useEffect(() => {
  if (Object.keys(listing || {}).length) {
    setEditListing(listing);
  }
}, [listing]);

问题2:嵌套对象location的更新逻辑错误

你更新location时直接将整个location对象替换为仅包含当前修改字段的新对象,自然会清空location下其他未修改的字段,同时你还误将字段值用数组包裹,导致值类型不符合预期。
修正后的表单处理逻辑:

const handleChange = (e) => {
    const { name, value } = e.target;
    const locationFields = ['country', 'city', 'state'];
    setEditListing((prevListing) => ({
      ...prevListing,
      // 判断当前修改的是否为location下的字段
      ...(locationFields.includes(name) 
        ? {
            location: {
              ...prevListing.location, // 保留原有location下的所有字段
              [name]: value // 覆盖当前修改的字段
            }
          }
        : { [name]: value }
      )
    }));
  };

如果你的location字段的输入框name属性用了location.city这类带前缀的命名,额外加个字段名拆分逻辑即可,上面的代码适配你当前name直接为city/country/state的场景。


内容的提问来源于stack exchange,提问作者Stinny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:54:03