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
相关产品推荐
相关产品推荐

