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

React处理接口数据新增selected字段存入state不生效问题

问题描述

加工接口返回的names数据时,尝试为types数组项新增selected字段,但最终拿到的数据里没有该字段,加工逻辑未生效。
接口返回原始JSON结构(示例1):

{
    "names": [
        {
            "id": 1,
            "Description": "descr",
            "types": [
                {
                    "id": 1,
                    "decription":"descr1"
                }
            ]
        }
    ]
}

期望得到的数据结构(示例2):

{
    "names": [
        {
            "id": 1,
            "Description": "descr",
            "types": [
                {
                    "id": 1,
                    "decription":"descr1",
                    "selected":true
                }
            ]
        }
    ]
}

原始问题代码:

export default function Display() {
    ...
    const init = async () => {
        const { data } = await axios.post("").then(res => {
            console.log(res)
            return res.names.map((item) => {
                return {
                    ...item,
                    types: item.types.map((t) => ({ ...t, selected: true }))
                };

            })
        })
        .catch(err => {
            console.log(err)
        })
        setNames(res.data.names)
    }

    useEffect(() => {
        init();
    }, [])

    const change = (id, value, all) => {
        setStandards((prev) =>
            prev.map((i) => {... }));
    };
    return (
        <>
            {selectionNames.map((item) => (...))}
        </>
    );
}
问题原因

代码存在3个核心错误,导致加工逻辑完全没有作用到最终的状态数据上:

  • axios返回的响应对象中,接口实际返回的业务数据存放在res.data字段下,你在then回调里直接取res.names得到的是undefined,根本没有读取到原始的names数组
  • 你在then回调中加工完成的数组,被赋值给了await返回的解构变量data,但后续调用setNames时传入的是作用域内不存在的res.data.names,既没有把加工后的数据传入状态更新方法,还存在变量引用错误
  • 渲染逻辑中使用的是selectionNames变量做遍历,如果你用来存储加工后names数据的状态变量名不是selectionNames,渲染时拿到的也不会是你加工后的结果
修正方案

不要混用await和.then()链式调用,避免出现作用域混乱、变量指向错误的问题,统一使用async/await + try/catch的写法梳理逻辑,修正后代码如下:

export default function Display() {
    // 注意:状态变量名要和setNames对应,比如 const [names, setNames] = useState([])
    ...
    const init = async () => {
        try {
            const res = await axios.post("")
            // 从响应中读取原始names数组
            const originNames = res.data.names
            // 执行字段加工逻辑
            const processedNames = originNames.map((item) => {
                return {
                    ...item,
                    types: item.types.map((t) => ({ ...t, selected: true }))
                }
            })
            // 将加工完成的数组存入状态
            setNames(processedNames)
        } catch(err) {
            console.log(err)
        }
    }

    useEffect(() => {
        init();
    }, [])

    const change = (id, value, all) => {
        setStandards((prev) =>
            prev.map((i) => {... }));
    };
    return (
        <>
            {/* 遍历渲染时使用存储加工后数据的状态变量 */}
            {names.map((item) => (...))}
        </>
    );
}

提示:如果确实需要混用await和.then(),要牢记.then()的返回值是await的最终结果,需要把加工后的数据保存下来,再传入状态更新方法,不要跨作用域引用链式调用里的临时变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:24:30