React Native升级Agora后计时归零调用endCall出现渲染报错
报错核心原因
- 你当前代码把
this.endCall()直接作为JSX三元表达式的分支返回值嵌入渲染流中,而endCall是用async关键字修饰的异步函数,调用后会自动返回一个Promise对象。 - React渲染时仅支持文本、数字、合法组件、
null、undefined作为可渲染子元素,直接将Promise对象作为渲染节点传入,就会触发“Objects are not valid as react child”的类型报错。 - 旧版本SDK下可正常运行的逻辑适配原因:旧版Agora SDK的
leaveChannel是同步执行方法,当时你的endCall没有加async修饰,调用后返回undefined(属于合法的空渲染值),因此不会触发渲染错误;升级SDK后leaveChannel变为异步返回Promise,你为了适配异步等待逻辑给endCall加上了async关键字,直接改变了这个函数的返回值类型,才引发了本次渲染异常。 - 按钮手动触发无异常的原因:按钮的
onPress是独立的事件回调,不需要将返回值作为渲染内容使用,即便回调返回Promise对象也不会影响React的渲染流程,因此功能表现正常。
正确修复方式
- 严格遵循React的渲染原则:渲染流程中只能放置纯渲染逻辑,所有带副作用的操作(比如退出频道、修改状态、页面跳转)绝对不能直接放在JSX的渲染分支中执行。
- 调整三元表达式的返回值:当通话计时归零时,直接返回
null(合法的空渲染占位,不会产生任何UI内容),将endCall的触发逻辑挪到计时更新的回调逻辑中执行,示例调整后的代码:const {minutes, seconds} = this.state; return ( <View style={{flex: 1, backgroundColor: 'black'}}> {/* 计时归零时返回空占位,不再直接调用endCall */} {minutes === 0 && seconds === 0 ? ( null ) : ( <View style={{justifyContent: 'center', alignItems: 'center'}}> <Text style={{ color: '#ffffff', backgroundColor: THEME_COLOR, borderRadius: 17.5 * vw, padding: 6, justifyContent: 'center', alignItems: 'center', fontSize: 14, }}> {minutes}:{seconds < 10 ? `0${seconds}` : seconds} </Text> </View> )} {this._renderVideos()} </View> ) - 在计时更新的状态回调中触发endCall:在每秒更新通话时长的
setState完成回调里,判断到计时归零时再执行endCall逻辑,示例:// 通话计时更新的原有逻辑 this.setState({ minutes: newMinutesValue, seconds: newSecondsValue }, () => { // 状态更新完成后再判断是否触发结束通话,避免在渲染流程中执行副作用 if (newMinutesValue === 0 && newSecondsValue === 0) { this.endCall(); } })
注意:不要用类似
{minutes ===0 && seconds ===0 && this.endCall()}这类写法临时绕过,这本质还是在渲染流程中执行副作用逻辑,容易因为React的组件重渲染导致endCall被多次重复调用,引发状态不一致的隐性问题。
内容的提问来源于stack exchange,提问作者Sitamarhi Mart
相关产品推荐
相关产品推荐

