前言
今天现场人员反馈了UAT环境的一个BUG,一个酒店的枚举页面没有展示,导致用户不能过滤特定的酒店,遇到问题第一时间让现场人员上阿里云查了对应的接口日志,发现其他接口返回都是正常的,但是30分钟内酒店的枚举接口(后面称为HotelEnumInterface)没有日志,这个时候就很疑惑了
于是通过Teams远程操作现成人员的电脑,发现NetWork中没有请求HotelEnumInterface,但是对应的CustomerDetailInterface返回是正常的,页面的逻辑大致如下
问题分析
关键代码如下
componentWillReceiveProps(nextProps) {
const { customerId } = this.props.customerInfo;
const { dispatch } = this.props;
if (nextProps.customer?.customerId !== customerId && nextProps.customer?.customerId) {
// Redux
dispatch({
type: 'customer/HotelEnumInterface',
payload: {
customerId: nextProps.customer?.customerId,
},
});
}
}
通过前后customerId的不同来判断是否需要请求HotelEnumInterface
发现问题之后,在本地环境,SIT环境都没有复现这个问题,代码逻辑仔细看过没有发现什么bug,PROD环境也没有反馈这个问题,这个时候整个人就陷入了自我怀疑,只能通过UAT环境看源码打断点,但是发现怎么都进入不到dispatch这个方法里面,nextProps中的customerId和this.props中的是一致的,就这样僵持了两个小时,期间尝试了各个方向都没能在本地复现问题,后面不知道怎么灵光一现,发现UAT环境的CustomerDetailInterface返回非常快,本地mock的接口我加了500ms的延迟,导致一直没有复现,将信将疑把500ms的延迟去掉,终于复现了问题,问题是复现了但是我们需要知道bug出现的根本原因
其实问题就出在
componentWillReceiveProps这个里面,执行顺序出了问题才导致customerId的判断逻辑出错导致HotelEnumInterface没有请求
页面显示正确情况下页面渲染流程
当CustomerDetailInterface返回很快的时候,就会产生问题
页面显示错误情况下页面渲染流程
生命周期
我们来先复习下React Class组件的生命周期的整个流程
根据生命周期图示,页面显示正确的情况,
CustomerDetailInterface的返回值会在运行中返回,这个时候props改变会触发componentWillReceiveProps函数,前后customerId不一致就会请求HotelEnumInterface接口
但是CustomerDetailInterface在页面渲染之前就返回了,那么之后的props都是没变化的,自然就不会触发componentWillReceiveProps,更不会请求HotelEnumInterface接口