检测displayName为null时报null is not an object错误如何解决
报错根因
抛出null is not an object (evaluating this.props.currentUser.displayName)不是displayName值为null导致的,是**this.props.currentUser本身在Firebase初始化完成前就是null**,直接访问一个null值的属性自然会触发运行时错误。
除了访问属性没做校验,你的代码还有几个会导致功能失效的问题:
userDataFetched直接挂在组件实例this上,没有存入state,值变更后不会触发组件重渲染,就算检测到displayName有效值,页面也不会从加载态切换setTimeout/clearTimeout用法错误:setTimeout调用后会返回一个数字类型的定时器ID,必须存储这个ID才能精准清除定时器,直接把函数本身传入clearTimeout没有任何清除效果- render方法里加载完成的分支没有返回实际页面内容,就算状态更新成功也会渲染空白
- 没有在组件卸载时清除定时器,容易造成内存泄漏和重复调用问题
修复实现
核心修改点:
- 嵌套属性访问加安全校验,优先确认
currentUser存在,再判断displayName是否为有效值,环境支持的话用可选链?.可以大幅简化写法 - 把加载状态存入
state,状态更新自动触发重渲染 - 单独存储定时器ID,在重试和组件卸载时正确清除定时器
- 补全加载完成后的页面返回逻辑
完整修复代码:
class MainPage extends Component { constructor(props) { super(props) this.state = { userDataFetched: false } // 存储定时器ID this.checkTimer = null this.checkUser = this.checkUser.bind(this) } componentDidMount() { this.checkUser() } componentWillUnmount() { // 组件卸载时清掉残留定时器 if (this.checkTimer) clearTimeout(this.checkTimer) } checkUser() { // 安全访问:先判断currentUser存在,再校验displayName有有效值 if (this.props.currentUser?.displayName != null) { this.setState({ userDataFetched: true }) clearTimeout(this.checkTimer) console.log("checkUser执行完成,displayName=", this.props.currentUser.displayName) } else { clearTimeout(this.checkTimer) this.checkTimer = setTimeout(this.checkUser, 500) console.log("等待用户数据创建,重试检测中,currentUser当前值:", this.props.currentUser) } } render() { if (!this.state.userDataFetched) { return ( <View> <Text>Loading...</Text> </View> ) } // 这里替换为你业务中登录后要展示的实际页面 return ( <View> <Text>主页内容,欢迎{this.props.currentUser.displayName}</Text> </View> ) } }
如果你的构建环境不支持可选链?.语法,把判断条件替换为逐层校验的写法即可,效果完全一致:
// 替换checkUser中的if判断条件 const currentUser = this.props.currentUser if (currentUser && currentUser.displayName !== null && currentUser.displayName !== undefined) { // 校验通过逻辑 }
内容的提问来源于stack exchange,提问作者Ákos Molnár
相关产品推荐
相关产品推荐

