惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
有赞技术团队
有赞技术团队
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
L
LINUX DO - 最新话题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
A
Arctic Wolf
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
小众软件
小众软件
Jina AI
Jina AI
The Cloudflare Blog
P
Palo Alto Networks Blog
AWS News Blog
AWS News Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
Know Your Adversary
Know Your Adversary
T
Threat Research - Cisco Blogs
L
Lohrmann on Cybersecurity
NISL@THU
NISL@THU
G
GRAHAM CLULEY
Project Zero
Project Zero
博客园_首页
博客园 - 三生石上(FineUI控件)
罗磊的独立博客
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
Latest news
Latest news
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
S
Securelist
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
IT之家
IT之家
Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Last Watchdog
The Last Watchdog
T
Tenable Blog
宝玉的分享
宝玉的分享
S
Secure Thoughts
P
Privacy & Cybersecurity Law Blog
量子位
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Security Archives - TechRepublic
Security Archives - TechRepublic

React

react 的旧文档网站,切换语言到中文,直接跳到新文档?? - V2EX react 这个技术栈到底是如何做到每天都有新发现的? 除了 next.js,在 2026 年,还有哪些 React 全栈框架推荐? - V2EX React 列表虚拟化如何实现使用 CSS Grid 布局的同时支持拖动元素? - V2EX 想不通, React 现代框架的设计者,为什么内置的 onClick 不默认防抖? - V2EX 关于低代码的选型,请佬们帮我分析一下 - V2EX 将 Markdown 文件导入为 React 组件 - 写作文档,即时获取交互式演示 - V2EX 现代 React 应用卡顿的主要原因是什么?组件库 vs 重渲染机制 - V2EX 前端开发进军 server 端还是问题很多 - V2EX 问一下, expo react native 的 TextInput 在小米系统下,显示有问题。大家有遇到么,如何解决。 - V2EX React Suite v6:面向现代化的稳健升级 - V2EX 各位总们,开发兼容到 ios 11 的 APP, RN 推荐吗 - V2EX expo-image 在使用时候必须要加 style 属性 ? - V2EX 佬们, 咨询一个前端 React 的开发效率问题, 就是如果想快速实现一个界面组件的效果,只需要 render 部分, 有什么好用的工具吗? - V2EX 2025 快过完了,有 ssr 需求的项目现在最佳选择是什么? - V2EX 在 react 中使用 signals 库 - V2EX react charts 技术选型 - V2EX 折腾了好几天总算在 windows 系统本地打包 expo 项目出 apk 了,分享下经验 - V2EX 一个 RN 小游戏代码修改的活 - V2EX 为什么 React-Native 总是昨天还能编译,今天就报错了 - V2EX React 19 下有什么方便点的组件? Arco Design 用起来还是有些问题 时隔多年再次用 react,请问 ahooks 的 useMemoizedFn 和 react 内置的 useEffectEvent 有什么异同? - V2EX 来个专业写 移动 web 前端的, React - V2EX 谁有闲工夫, React,帮忙定位并处理下 BUG react antd 就是包了巧克力的屎 - V2EX 提问一个 React 的问题 React 多人开发怎么确保性能,有没有最佳实践 - V2EX zustand create 出来的 useStore,需不需要 destory? - V2EX 关于 React: - V2EX Metis UI:下一代 React 组件库,重新定义前端开发体验 - V2EX React 组件库 Gluestack 出现多个恶意软件包 gpt 给我搞懵了,是我对 Suspense 理解有误吗? 有用 LiveKit 开发过视频语音会议系统的嘛 - V2EX RN 怎么构建输出 Java 的原生工程啊? 大佬们,有没有好用的 react.js 画布组件? 技术文章翻译: React 协调机制 - V2EX 不知道是 react 不行还是阿里不行, 或者是我电脑不行? 访问阿里云卡卡的.滚动一愣一愣的. 不敢相信在 2025,怎么自己 build/bundle + self-host 一个 ESM 版本的 react.js 和 react-dom.js 也是一个找不到官方答案的问题。问了 AI,答案也不靠谱 - V2EX 有没有熟悉 react native 的老哥,求帮忙看个问题 - V2EX React 写的越多,就越想直接操作 DOM - V2EX react native 有类似 antd/x 的 ai 对话组件库吗 - V2EX react 最佳技术栈是什么? - V2EX 是不是都用 expo-image 了,分享下 react-native-turbo-image - V2EX 用 AI 写了个 react 的资讯网站,才发现 SEO 很差,怎么办 - V2EX 反思,我写的前端的 react 味是不是太重了 - V2EX 小白求助,React 项目无法修改 - V2EX 被 antd 惯坏了,别的组件库用的很难受,大家有这种感觉吗? - V2EX React 学习曲线要比 Vue 陡峭许多呀 - V2EX 请教一个关于 useEffect 依赖的问题 - V2EX
请教一个 react native FlatList 的问题 - V2EX
letterLim · 2025-02-18 · via React
letterLim

4

letterLim      2025 年 2 月 19 日

const getMessageList = useMemo(() => (startPage: number, endPage: number) => {
return allMessageList
.slice(startPage * PAGE_SIZE, (endPage + 1) * PAGE_SIZE)
}, [allMessageList, PAGE_SIZE])

useEffect(() => {
setMessageList(getMessageList(0, 0))
}, [])

useEffect(() => {
if (startPage === 0 && isAtBottom) {
setMessageList(getMessageList(startPage, endPage));
}
}, [startPage, endPage, getMessageList, isAtBottom]);

const onReachTop = useCallback(() => {
console.log('onReachTop');
if (isJumpingToUnread) {
return;
}
if (startPage > 0) {
const _startPage = startPage - 1;
setStartPage(_startPage);
setMessageList(getMessageList(_startPage, endPage))
}
}, [startPage, isJumpingToUnread, endPage, getMessageList]);

const onReachBottom = useCallback(() => {
console.log('onReachBottom', isJumpingToUnread);
if (isJumpingToUnread) {
return;
}
if (messageList.length < allMessageList.length) {
setEndPage(pre => {
setMessageList(getMessageList(startPage, pre + 1))
return pre + 1
})
}
}, [messageList.length, setEndPage, startPage, allMessageList.length, isJumpingToUnread, getMessageList]);

const goUnreadMessage = useCallback(() => {
setIsJumpingToUnread(true);
setUnreadNum(0)
let _messageList: any = []
const startPage = Math.floor(unreadNum / PAGE_SIZE) > 1 ? Math.floor(unreadNum / PAGE_SIZE) - 1 : 0;
let endPage = startPage + 1;
_messageList = getMessageList(startPage, endPage)
const index = _messageList.findIndex(item => item._id === lastMessageId.current)
if (index % PAGE_SIZE === 0) {
endPage = startPage + 1
}
setStartPage(startPage);
setEndPage(endPage);
setMessageList(_messageList)
}, [allMessageList.length, getMessageList]);

useEffect(() => {
if (isJumpingToUnread && lastMessageId.current) {
const index = messageList.findIndex(item => item._id === lastMessageId.current)
if (index !== -1) {
const timer = setTimeout(() => {
clearTimeout(timer)
flatListRef.current?.scrollToIndex({
index,
animated: true,
viewPosition: 0.1,
})
}, 200)
}
}
}, [messageList.length, isJumpingToUnread]);

useEffect(() => {
if (!lastMessageId.current && allMessageList.length >= (unreadNum-1) && unreadNum) {
lastMessageId.current = allMessageList[unreadNum-1]?._id;
}
}, []);

useEffect(() => {
const initMessageList = () => {
setStartPage(0)
setEndPage(0)
setMessageList(getMessageList(0, 0))
InteractionManager.runAfterInteractions(() => {
flatListRef?.current?.scrollToOffset({ offset: 0, animated: true })
})
}
EventCenter.on('init_message_list', initMessageList)
return () => {
EventCenter.remove('init_message_list', initMessageList)
}
}, [getMessageList])

const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
const isBottom = event.nativeEvent.contentOffset.y <= 10;
setIsAtBottom(isBottom);
}, []);

const onScrollToIndexFailed = useCallback((info: {
index: number;
highestMeasuredFrameIndex: number;
averageItemLength: number;
}) => {
const offset = info.index * info.averageItemLength
flatListRef.current?.scrollToOffset({ offset: offset, animated: true })
}, []);

const threshold = isJumpingToUnread ? 0.1 : 1

<FlatList
removeClippedSubviews
windowSize={20}
onStartReachedThreshold={threshold}
onEndReachedThreshold={threshold}
onEndReached={onReachBottom}
onStartReached={onReachTop}
onScroll={handleScroll}
scrollEventThrottle={17}
keyboardDismissMode="on-drag"
maxToRenderPerBatch={10}
initialNumToRender={10}
onTouchStart={() => {
setIsMore(false)
setEmojiKeyboardVisible(false)
}}
onScrollBeginDrag={() => {
setIsJumpingToUnread(false);
}}
maintainVisibleContentPosition={startPage && !isAtBottom ? {
minIndexForVisible: 1,
autoscrollToTopThreshold: 10
}:undefined}
onScrollToIndexFailed={onScrollToIndexFailed}
inverted
contentContainerStyle={{ paddingHorizontal: 10 }}
scrollsToTop={false}
data={messageList}
keyExtractor={item => item._id}
showsVerticalScrollIndicator
ref={flatListRef}
renderItem={renderItem}