React Native中await失效,多次打印重复结果的问题求助
问题:React Native异步请求后render多次输出逐步增加的数组
我是React Native初学者,执行异步方法后在render中打印结果,函数似乎未执行完成就多次输出。
我的代码:
export default class UserList extends Component { constructor(){ super(); this.state={ author_name: [] } } async getPosts(){ var sid=this.props.route.params.value_sid var did=this.props.route.params.value_did const utils=new Utils(); //now i resolve the promise after a network request const y=await utils.getPost(sid,did).then((responseJson) => { const personArray = responseJson?.posts ?? []; personArray.map((data) => { //i extract the authorName field from the json file that I read from the network and set state this.setState({ author_name: [...this.state.author_name, data.authorName], }) }) }) } render(){ console.log("author name is: ",this.state.author_name) }
当前console.log输出(逐步增加的数组):
author name is: ["Joe"] author name is: ["Joe", "unnamed"] author name is: ["Joe", "unnamed", "Jude"] author name is: ["Joe", "unnamed", "Jude", "Jude"] author name is: ["Joe", "unnamed", "Jude", "Jude", "Yuppie"] author name is: ["Joe", "unnamed", "Jude", "Jude", "Yuppie", "Ratatatatata55555"] author name is: ["Joe", "unnamed", "Jude", "Jude", "Yuppie", "Ratatatatata55555", "Bill"] author name is: ["Joe", "unnamed", "Jude", "Jude", "Yuppie", "Ratatatatata55555", "Bill", "Stacy"] author name is: ["Joe", "unnamed", "Jude", "Jude", "Yuppie", "Ratatatatata55555", "Bill", "Stacy", "Matt"] author name is: ["Joe", "unnamed", "Jude", "Jude", "Yuppie", "Ratatatatata55555", "Bill", "Stacy", "Matt", "Jess"]
期望输出(仅最终完整数组):
["Joe", "unnamed", "Jude", "Jude", "Yuppie", "Ratatatatata55555", "Bill", "Stacy", "Matt", "Jess"]
我知道await会等待方法执行完毕,但此处await似乎失效,请问该如何实现需求?原因是什么?
原因分析
await并没有失效,它确实等待了utils.getPost的网络请求完成。问题出在请求完成后的处理:你在personArray.map循环里逐个调用setState,而每一次setState都会触发组件重新渲染,所以render会执行多次,每次数组新增一个元素。- 另外,直接使用
this.state.author_name拼接新元素存在风险,因为setState是异步操作,批量更新时可能获取到旧的state值,导致状态更新异常。
解决方案
先一次性收集所有需要的authorName到一个新数组,再调用一次setState更新状态,这样只会触发一次组件渲染,就能得到最终完整的数组。
修改后的代码:
export default class UserList extends Component { constructor(){ super(); this.state={ author_name: [] } } async getPosts(){ const sid = this.props.route.params.value_sid const did = this.props.route.params.value_did const utils = new Utils(); // 等待网络请求完成,直接用await接收返回值,避免嵌套then const responseJson = await utils.getPost(sid, did); const personArray = responseJson?.posts ?? []; // 一次性提取所有authorName到新数组 const authorNames = personArray.map(data => data.authorName); // 仅调用一次setState更新状态 this.setState({ author_name: authorNames }) } render(){ console.log("author name is: ", this.state.author_name) // 注意:原代码缺少render的返回值,实际项目中请替换为你的组件JSX return null; } }
补充说明
- 取消了嵌套的
.then,直接用await接收请求结果,代码更简洁易读。 - 通过
map一次性生成完整的作者名数组,再统一更新状态,避免了多次渲染的问题。 - 同时规避了异步更新state时可能出现的状态不一致问题。
内容的提问来源于stack exchange,提问作者Elly
相关产品推荐
相关产品推荐

