React中对对象数组使用.map()时刷新页面后组件不渲染如何解决
问题根因与修复方案
核心根因1:Firebase数据获取逻辑异步问题
你写的getMembers方法是同步返回空数组的,Firebase的ref.on("value")是异步回调逻辑,回调执行的时候函数早就已经把空的membersList返回出去了,首次渲染可能因为特殊时序刚好拿到数据,刷新后时序变化就返回空数组。
修复代码:把getMembers改成返回Promise的异步函数:
//get array of members from firebase export const getMembers = () => { return new Promise((resolve, reject) => { const membersList = []; // 用once只获取一次数据,不要用on长期监听避免内存泄漏 membersRef.once("value", function (snapshot) { snapshot.forEach(function (childSnapshot) { const item = childSnapshot.val(); item.key = childSnapshot.key; membersList.push(item); }); resolve(membersList); }, (error) => { reject(error); }); }) };
核心根因2:数据拉取触发时机错误
你现在只有在谷歌登录成功GOOGLE_SIGNIN_SUCESS触发的时候才会拉取成员列表,页面刷新后如果登录状态是本地持久化的,不会再次触发登录成功的action,所以根本不会执行拉取数据的逻辑,自然拿不到membersDetail。
修复方案:
- 增加页面初始化时的触发逻辑,比如在App组件挂载时判断用户已登录就调用
getMembersStart,或者在saga里增加监听页面初始化的action。 - 同时修正reducer的状态重置逻辑,
GET_MEMBER_SUCESS分支漏了把isGettingMembers设为false:
case MemberActionTypes.GET_MEMBER_SUCESS: return { ...state, members: action.payload, errorMessage: "", isGettingMembers: false, // 补上状态重置 };
核心根因3:组件渲染写法问题
- map遍历的key属性放错了位置,key需要绑定在map返回的最外层节点上,不能放在内层div,否则React识别节点变化会出现异常,导致渲染失效。
- 拼写错误:
classname应该是React要求的驼峰写法className - 建议增加可选链
?.,避免初始化时membersDetail为null导致map报错。
修复后的组件渲染部分:
return ( <div className="book"> {membersDetail?.map(({ name, phoneNumber }) => ( <div className="select-members" key={phoneNumber}> {/* key移到map返回的最外层节点 */} <div className="member" onClick={takeToBookNav}>{name}</div> </div> ))} </div> );
内容的提问来源于stack exchange,提问作者Biki Thakur
相关产品推荐
相关产品推荐

