React Native Navigation:有条件地渲染标签栏徽章不起作用?
React Native Navigation: Conditionally render tab bar badge not working?
我正在尝试为我的通知选项卡显示一个选项卡栏徽章。如果用户有通知,在后端写入通知后,我将用户“hasNotifications”的字段设置为 true。单击通知选项卡后,我将“hasNotifications”设置为 false。
这是我的实现:
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>
);
}
控制台日志显示侦听器正在工作,returns true/null 根据用户是否有通知。但是标签栏徽章没有出现。我该如何解决这个问题?
编辑:看起来当我设置 tabBarBadge: renderBadge()
时,徽章从未出现。当我设置 tabBarBadge: renderBadge
时,徽章始终显示。侦听器工作正常,但这不是。
编辑 2:我将函数更改为 const renderBadge = () => {
,但它仍然不起作用。
我知道 react(对于浏览器)比 react-native 更好,但是如果范式相同,您应该更改以下方面:
- 不是直接在函数范围内改变一个变量,而是利用
useState
来保存布尔值;更改其 setter 函数提供的值
- 这将做出反应,允许在发生变化时注意到变化并做出反应。
- 您的 Firebase 访问可能是某种副作用,因此您应该使用
useEffect
,也许 Firebase.auth().currentUser.uid
作为依赖项。
- 这可以防止仅仅因为 React 决定重新渲染组件而建立多个订阅。
- 您还应该从
useEffect
回调中 return 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
我个人的建议是将此代码段中的 null
替换为 false
以使 API 更加清晰。
我正在尝试为我的通知选项卡显示一个选项卡栏徽章。如果用户有通知,在后端写入通知后,我将用户“hasNotifications”的字段设置为 true。单击通知选项卡后,我将“hasNotifications”设置为 false。
这是我的实现:
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>
);
}
控制台日志显示侦听器正在工作,returns true/null 根据用户是否有通知。但是标签栏徽章没有出现。我该如何解决这个问题?
编辑:看起来当我设置 tabBarBadge: renderBadge()
时,徽章从未出现。当我设置 tabBarBadge: renderBadge
时,徽章始终显示。侦听器工作正常,但这不是。
编辑 2:我将函数更改为 const renderBadge = () => {
,但它仍然不起作用。
我知道 react(对于浏览器)比 react-native 更好,但是如果范式相同,您应该更改以下方面:
- 不是直接在函数范围内改变一个变量,而是利用
useState
来保存布尔值;更改其 setter 函数提供的值- 这将做出反应,允许在发生变化时注意到变化并做出反应。
- 您的 Firebase 访问可能是某种副作用,因此您应该使用
useEffect
,也许Firebase.auth().currentUser.uid
作为依赖项。- 这可以防止仅仅因为 React 决定重新渲染组件而建立多个订阅。
- 您还应该从
useEffect
回调中 returnFirebase...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
我个人的建议是将此代码段中的 null
替换为 false
以使 API 更加清晰。