关于 Taro 的 ScrollView 在Dom结构发生变化会自动回滚到顶部解决方案和原因

本文揭示了在Taro小程序中,ScrollView在同级节点增删时自动回滚顶部的bug原因,通过分析React组件状态管理机制,提出使用Block组件避免重载。并给出了修复代码示例,帮助开发者理解和解决此类问题。
摘要由CSDN通过智能技术生成

使用Taro开发小程序时候发现 ScrollView 会在同级节点发生增删情况下会自动会滚ScrollView到顶部,经过多次验证和查阅Taro原理发现这是Taro自身bug

出现回滚顶部bug的演示代码

下面有一个列表和按钮,点击按钮会出现加载更多的字样。但是当我们点击按钮时候,ScrollView就会惊奇发生会滚到顶部的现象。

const App: React.FC = () => {
	const [show, setShow] = useState<boolean>(false)
	const list = new Array(1000)
	
	const onClick = (): void => setShow(true)
	
	return (
		<View>
			<View onClick={onClick} >
				按钮
			</View>
			<ScrollView>
				{list.map(_, index) => (
					<View key={index}>{index}</View>
				)}
			</ScrollView>
			{show && <View>加载更多</View>}
		</View>
	)
}

出现BUG原因

因为Taro其实是将React所有组件的state更新归级Page统一进行管理即楼级组件对应的state是

// 初始化state
state = {
	Page: [ View, ScrollView ]
}

那么新增和删除节点就是

const oldPage = this.state.Page
this.setState({ 
   Page: [ ...oldPage, View ]
})

这样微信进行diff时候认为是一个全新的数组,这样整个楼级组件都会重新创建。所以ScrollView会被重新创建,就会出现ScrollView自动会滚顶部的情况。

解决方案

  • 避免同级节点操作,这个几乎很难。所以抛弃
  • 使用 Block 组件包裹ScrollView的同级节点,那么我们更新节点时候就是单独对数组某个元素更新。这样就不会影响到ScrollView元素。

当我们用Block包裹 加载更多 发生更新的行为将是这样,那么在微信小程序diff对比时候只是楼层数组里面某个元素内容发生变化,就不会对ScrollView节点进行重建

const oldPage = this.state.Page
oldPage[2] = [ View ]
this.setState({ Page: oldPage })
解决bug代码
const App: React.FC = () => {
	const [show, setShow] = useState<boolean>(false)
	const list = new Array(1000)
	
	const onClick = (): void => setShow(true)
	
	return (
		<View>
			<View onClick={onClick} >
				按钮
			</View>
			<ScrollView>
				{list.map(_, index) => (
					<View key={index}>{index}</View>
				)}
			</ScrollView>
			<Block>
				{show && <View>加载更多</View>}
			</Block>
		</View>
	)
}
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨周龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值