React Native Navigation:有条件地呈现标签栏徽章不工作?



我正在尝试为我的通知选项卡显示标签栏徽章。如果用户有通知,在后端写入通知后,我为用户设置一个字段&;hasNotifications"是真实的。点击通知选项卡后,我设置了&;hasNotifications"假的。

这是我的实现:

function renderBadge() {
Firebase.firestore()
.collection('users')
.doc(Firebase.auth().currentUser.uid)
.onSnapshot(function(doc) { 
if (doc.data().hasNotifications) {
console.log("true")
return true
}
else {
console.log("null")
return null
}

})
}

//Bottom Tabs
function Tabs() {

return (
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
activeTintColor:"#FFFFFF",
inactiveTintColor:"#696969",
style: {
backgroundColor: '#000000',
borderTopColor: "transparent"
},
}}>
<Tab.Screen 
name="Notificaton" 
component={Notification}
options={{
tabBarLabel: ' ',
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-notifications" size={size} color={color} />
),
tabBarBadge: renderBadge() <----- Render red dot if true, no red dot if null
}}
/>  
</Tab.Navigator>
);
}

控制台日志告诉我监听器正在工作,并根据用户是否有通知返回true/null。但标签栏徽章不显示。我该如何解决这个问题?

编辑:看起来当我设置tabBarBadge: renderBadge()时,徽章从未显示。当我设置tabBarBadge: renderBadge时,徽章总是显示出来。监听器工作正常,但这不是。

编辑2:我把功能改为const renderBadge = () => {,它仍然不起作用。

我知道react(对于浏览器)比react-native更好,但如果范式相同,您应该更改以下方面:

  • 不直接改变函数作用域中的变量,而是使用useState来保存布尔值;更改其setter函数提供的值
    • 这将允许在发生变化时注意到它并使它——react。
  • 你的Firebase访问可能是某种副作用,所以你应该使用useEffect,也许与Firebase.auth().currentUser.uid作为一个依赖。
    • 这可以防止因为react决定渲染组件而建立多个订阅。
    • 您还应该从useEffect回调中返回Firebase...onSnapshot(...)的结果,以便在组件不再需要时正确地销毁firebase订阅-参见https://firebase.google.com/docs/reference/node/firebase.firestore.CollectionReference#returns-=-void

结果可能类似于:

function useNotificationsBadge() {
const [hasNotifications, setHasNotifications] = useState(null);
const userId = Firebase.auth().currentUser.uid;
useEffect(
() => Firebase.firestore()
.collection('users')
.doc(userId)
.onSnapshot(function(doc) {
const newHasNotifications = doc.data().hasNotifications ? true : null;
setHasNotifications(newHasNotifications);
}),
[userId]
);
return hasNotifications;
}

在你的组件中,你可以写;

...
const hasNotifications = useNotificationsBadge();
...
tabBarBadge: hasNotifications

我个人的建议是用false代替null,以使API更清晰。

最新更新