React项目中接口返回值首次打印正常后续变为1的问题排查
问题根因
错误出现在App.js的接口请求回调逻辑中:
Array.push()方法的返回值是新数组的长度,而非修改后的数组本身。你当前代码let uData = uploadsData.push(resp)中,uData拿到的就是push后的数组长度1,调用setUploadsData(uData)直接把状态从数组改成了数字1,这就是后续打印拿到1的核心原因。- 同时你直接修改state原值(
uploadsData.push直接修改了useState返回的数组,属于非法的原地修改state操作),不符合React状态不可变的开发要求。
修复方案
把请求回调里的状态更新逻辑替换为符合不可变原则的写法即可:
// 删掉原有错误写法 // let uData = uploadsData.push(resp) // setUploadsData(uData); // 替换写法1:如果需要把接口返回内容追加到原有数组末尾 setUploadsData(prevState => [...prevState, resp]); // 替换写法2:如果接口返回的resp就是完整的上传列表,不需要保留旧值(绝大多数场景是这个需求) // 注意:axios返回的业务数据默认存放在resp.data字段下,你之前直接存整个resp对象会包含大量无关的响应元信息 setUploadsData(resp.data);
其他代码优化&最佳实践建议
- 路由组件传参不要用匿名函数作为
component属性值,会导致组件不必要的重挂载:
原有写法<Route component={() => <Gallery data={uploadsData}/>} />会在每次路由更新时生成新的匿名组件,触发Gallery反复卸载挂载,建议改为render属性写法:
<Route render={() => <Gallery data={uploadsData}/>} />
Gallery.js中的useEffect要补全依赖项:
你当前Gallery里的useEffect依赖是空数组,只会在组件第一次挂载时执行一次,后续data更新不会触发回调执行,修改为:
useEffect(() => { console.log("FROM App.js INSIDE Gallery.js"); console.log(data); }, [data]); // 将data加入依赖数组
- 无权限跳转逻辑建议前置:无token的情况可以直接在页面初始化时判断跳转,不需要先发送接口请求再处理跳转,减少无效请求。
App.js中的useEffect要补全依赖项:当前useEffect依赖是空数组,但内部用到了authToken、push等变量,建议加入依赖数组或者用useCallback包裹getUploads函数,避免闭包陷阱。
内容的提问来源于stack exchange,提问作者sp92
相关产品推荐
相关产品推荐

