Redux状态更新时如何让关联的函数式组件自动重新渲染?
问题根因
- 当前拉取用户数据用的是Firestore一次性
get()请求,仅在调用时拉取一次数据,用户更新头像后没有主动重新触发拉取逻辑,Redux内的用户数据不会自动更新,只有重启App重新调用拉取接口才能拿到新数据。 - 若头像更新后存储uri未发生变化(比如新头像直接覆盖旧存储路径),React Native的Image组件默认会缓存同uri的资源,不会主动拉取最新资源,也会导致界面不更新。
- 组件内
useEffect用可选链值currentUser?.pp作为依赖,React依赖检测对可选链的响应可能存在异常,同时内部多维护了一层image状态也增加了不同步的风险。
修复方案
1. 同步Redux最新用户数据
两种方案二选一即可:
- 方案1:换成Firestore实时快照监听,用户数据更新后自动同步到Redux
export function fetchUser() { return (dispatch) => { const uid = firebase.auth().currentUser.uid; // 替换get为onSnapshot实时监听 const unsubscribe = firebase .firestore() .collection('users') .doc(uid) .onSnapshot((snapshot) => { if (snapshot.exists) { dispatch({ type: USER_STATE_CHANGE, currentUser: snapshot.data() }); } else { console.log('does not exist'); } }, (error) => console.log(error)); // 返回取消监听函数,可在App卸载时调用避免内存泄漏 return unsubscribe; }; }
- 方案2:不用实时监听的话,在用户头像上传成功、已经更新完Firestore用户数据的回调里,手动调用一次
fetchUser()拉取最新数据更新Redux。
2. 强制跳过Image缓存
修改头像渲染逻辑,强制跳过本地缓存拉取最新资源:
<Avatar.Image size={100} source={{ uri: image, cache: 'reload' // 跳过本地缓存强制拉取最新资源 }} />
3. 简化组件逻辑(可选)
可以删除内部冗余的image状态和useEffect,直接用props传入的currentUser渲染,减少不同步风险:
function DrawerProfilePicture(props) { const { currentUser } = props; if (!currentUser) { return <View></View>; } return ( {!currentUser.pp ? ( <Image style={{ width: 100, height: 100 }} source={require('../../assets/default.png')} /> ) : ( <Avatar.Image size={100} source={{ uri: currentUser.pp, cache: 'reload' }} /> )} ); } const mapStateToProps = (store) => ({ currentUser: store.userState.currentUser, }); export default connect(mapStateToProps, null)(DrawerProfilePicture);
内容的提问来源于stack exchange,提问作者Cli Ad
相关产品推荐
相关产品推荐

