情景回顾:订单列表统计数量的展示是通过websocket推送的数据来展示的。将随送的数量经过计算后用redux存到store里。问题出现在第一次推送订单数量后不会展示,刷新一下页面才展示。经过打断点排查,发现每次从props里拿的计算好的订单数量都是0。似乎props里订单数量没有更新。但store里明明是更新了的。看了下代码,感觉问题估计出在闭包问题上。
useEffect(()=>{
window.eventBus.on('wsShopOrderStatusNum', makeOrderStatusStatistic);
}, []);
const makeOrderStatusStatistic = (data = {})=>{
let content = data.plainBody;
let temp = {};
// 调用触发订单数量统计后WS会针对当前用户立即推一次有权限的全部门店数据
if(content.eventType === 'IM_EVENT_ALLSHOP_ORDER_STATUS_NUM'){
temp = Object.assign({}, props.order.orderStatistic);
content.paramMap.shopStatusStatistics.forEach(v=>{
temp[v.shopId] = v.statusStatistics;
});
}
// 后续WS推送的数据为单店数据
if(content.eventType === 'IM_EVENT_SINGSHOP_ORDER_STATUS_NUM'){
temp = {...props.order.orderStatistic};
temp[content.paramMap.shopId] = content.paramMap.statusStatistics;
}
makeOrderCount(temp);
props.setOrderStatistic({...temp});
};
每次事件推送过来,props里的值都是最初的数据。首先想到的就是改下props的取值方式。用useRef先把props存一下。后续props更新,调用他的引用就行了,问题解决。
const $this = useRef(props);
useEffect(()=>{
window.eventBus.on('wsShopOrderStatusNum', makeOrderStatusStatistic);
}, []);
useEffect(()=>{
$this.current = props;
}, [props]);
const makeOrderStatusStatistic = (data = {})=>{
let content = data.plainBody;
let temp = {};
// 调用触发订单数量统计后WS会针对当前用户立即推一次有权限的全部门店数据
if(content.eventType === 'IM_EVENT_ALLSHOP_ORDER_STATUS_NUM'){
temp = Object.assign({}, $this.current.order.orderStatistic);
content.paramMap.shopStatusStatistics.forEach(v=>{
temp[v.shopId] = v.statusStatistics;
});
}
// 后续WS推送的数据为单店数据
if(content.eventType === 'IM_EVENT_SINGSHOP_ORDER_STATUS_NUM'){
temp = {...$this.current.order.orderStatistic};
temp[content.paramMap.shopId] = content.paramMap.statusStatistics;
}
makeOrderCount(temp);
props.setOrderStatistic({...temp});
};
类似的hooks闭包问题,还需要从根上去理解一下。
相关文章地址:
https://mp.weixin.qq.com/s/0P7eWSNQNKWroDIlcgHBVw
https://mp.weixin.qq.com/s/uJe7gLjFX5O4lA2ezc656A
转载请注明带链来源:春语精椿