如何在侦听值事件时延迟加载



我正试图为大量(约100K(的数据点构建一个摘要实时视图面板。当前版本在初始加载后可以正确地实时监控更改,但在第一次加载时,仪表板在大约4秒内没有数据。

数据已被反规范化,因此by_date具有如下结构,每个日期包含数千个uid键,只有可用日期与仪表板相关。

{
[date: string]: {
[uid: string]: {
values: number;
status: boolean;
};
};
}

现场聆听功能是一个波纹管。


function observe() {
db.ref("by_date")
.orderByValue()
.limitToLast(1) // only last available date is loaded
.on("value", function (dataSnapshot) {
const data = dataSnapshot.val();
// data json object is put in a state variable
// changes on the state will trigger a parial dashboard refresh
setLastDayReportsDb(data); 
});
}

我试图找到的是一种方法,将数据作为流或分页引入,但仍然保持侦听值的任何更改,以便保留仪表板的实时实时方面。

Hi实际上有一种方法可以延迟加载数据并侦听更改。。。

假设你有100条未读聊天信息,可能还有更多未读信息,你想10乘10听。

这是一个想法,你需要一个可以监听实时变化的自定义钩子,这个自定义钩子有一个参数,比如说";loadby:number">
每次Flatlist到达末尾时,我们都应该找到一种方法来卸载该钩子并再次装载。

这是示例代码。

这是监听改变的钩子


const useChatListListener = (counted: number) => {
const [list, setList] = useState<ChatInterface.ChatListItem[]>()

useEffect(() => {
const uid = commonmethods.getUID();
let onValueChange: any = null
onValueChange = database.ref(`/chats/${uid}`).orderByChild('read').equalTo(false).limitToFirst(counted).on('value', (snapshot: any) => {
// listening should return an empty array at least, in this way we understand the first listening is occured.
const modifiedresponse = commonmethods.createArrayFromObject<ChatInterface.ChatListItem>(snapshot.val())
if(snapshot) setList(modifiedresponse)
else setList([])
})
return () => {
if(onValueChange) {
database.ref(`/chats/${uid}`).off('value', onValueChange);
}
}
}, [])
return list
}

而这就是实际的平淡主义者将懒散地听信改变


interface ListenerComponentProps {
counted: number
callback: (data: any) => void
}
const ChatListenerManager: React.FC<ListenerComponentProps> = (props) => {
const listdata = useChatListListener(props.counted)
useEffect(() => {
console.log("I AM IN")

return () => {
console.log("I AM OUT")
};
}, [])
useEffect(() => {
props.callback(listdata)
}, [listdata])
return null
}
interface Props {}
const LOAD_BY = 10
const ChatList: React.FC<Props> = (props) => {
const [reload, setReload] = useState({ status: true, by: 10 })
const [listData, setListData] = useState<ChatInterface.ChatListItem[]>()
const [initialLoad, setInitialLoad] = useState(false)
const [bottomloading, setBottomLoading] = useState(false)
const [keepLoading, setKeepLoading] = useState(true)
useEffect(() => {
if(!reload.status) {
/**
* If you hit bottom and the requested number is greater than returned array length
* then we shouldn't update the next requested number and also we should allow to request again when hitting to end too
* There could be more incoming unread messages so there is no end actually.
*/
setReload({ status: true, by: keepLoading ? reload.by + LOAD_BY : reload.by })
}
}, [reload])
const listListener = (data: ChatInterface.ChatListItem[]) => {
if(data && data.length >= 0) {
setListData(data)
if(reload.by > data.length) setKeepLoading(false)
!initialLoad && setInitialLoad(true)
}
}
const loadMore = () => {
setReload({ status: false, by: reload.by })
}
return (
<View style={styles.container}>
// This is the actual listener and lazy loader, this does the both thing together
{reload.status && <ChatListenerManager counted={reload.by} callback={listListener} />}
{
<FlatList
data={listData}
renderItem={({ item }) => <ChatListItem {...item} />}
showsHorizontalScrollIndicator={false}
onEndReached={() => {
if(initialLoad && !bottomloading) loadMore()
}}
/>
}
</View>
)
}

通过这种方式,我们有一个使用监听器钩子的组件,并且我们正在挂载&当我们触底时就把它卸下来。当我们增加";计数";它会加载更多的聊天信息,并且也会监听它们。同样重要的是,当我们卸载它时,我们也安全地删除了侦听器,没有副作用。

最新更新