reactjs - ScrollView 位置在子组件重新渲染时重新启动(更新)
问题描述
我有一个问题(这可能是我在渲染周期中忽略的问题)在更新其某些子组件时维护两个不同滚动视图的位置。
我有一个视图层次结构,例如:
<ScrollView vertical scrolling ability>
...
<ScrollView horizontal and vertical scrolling ability>
...
<Matrix>
<Cell updateCellStatusHandler={handler}>
</Matrix>
...
</ScrollView>
</ScrollView>
因此,内部单元格的更新正在重置单元格状态更新时的滚动,这会产生一种超级奇怪的体验,用户必须向下/向左/向右滚动才能继续与具有我拥有的状态的单元格矩阵交互。
我尝试使用保存 scrollOffset (x,y)useState
但如果我更改某些单元格,状态将重置为 (0,0),这是我的初始状态。
const [scrollOffset, setScrollOffset] = useState({
scrollX: 0,
scrollY: 0,
})
但没有运气。
<ScrollView
{...props}
scrollEventThrottle={16}
ref={scrollReference}
// tslint:disable-next-line: jsx-no-lambda
onScroll={event => {
setScrollOffset({
scrollX: event.nativeEvent.contentOffset.x,
scrollY: event.nativeEvent.contentOffset.y,
})
}}
onScrollEndDrag={event => {
console.log(event.nativeEvent.contentOffset.y)
console.log(event.nativeEvent.contentOffset.x)
}}
>
{props.children}
</ScrollView>
解决此问题的一种可能方法是拥有一种机制,允许我在更新之前保存滚动位置。但这会使组件之间的通信等复杂化很多。顺便说一下,单元格状态更新是通过 Redux 处理的。
如果你们中的一些人能给你们带来一些启示,那就太好了。
---- UPDATE 1(添加面板组件的代码)----
父组件是:
<View style={styles.container}>
<CustomScrollView enableResetScrollToCoords={false}>
<Section>
<WhiteContainer>
<View style={styles.rateContainer}>
<DescriptionTextStatus
statusText={getMessageForRate(availabilityRate)}
descriptionText={getDescriptionForRate(
availabilityRate,
isTeacher,
)}
icon={getImageForRate(availabilityRate)}
/>
</View>
</WhiteContainer>
</Section>
{!loggedUserIsTeacher() && <AvailabilityStart />}
<AvailabilityPanel />
<AvailabilityStatus />
<AvailabilityButtonSave />
</CustomScrollView>
</View>
可用性面板是其中一个孩子
export const AvailabilityPanel: React.FunctionComponent<{}> = () => {
const panel: Cell[][] = useSelector((state: ReduxStore) => {
return get(state.entities, 'availability.panel', undefined)
})
if (panel === undefined) {
return <Nothing />
}
return (
<Section>
<WhiteContainer>
<LinearGradient
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
colors={[Palette.White, Palette.White68]}
>
<View style={styles.rateContainer}>
<DescriptionTextStatus
statusText={strings.warning}
descriptionText={strings.selectionMessage}
icon={'clock'}
/>
<View style={styles.separator} />
</View>
<View style={styles.container}>
<ScrollView
style={styles.scrollView}
directionalLockEnabled={false}
horizontal={true}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
<View style={styles.contentContainer}>
<View style={styles.weekdaysContainer}>
<PanelHeader weekdays={weekdays} />
</View>
<View style={styles.rowsContainer}>
{hours.map((hourLabel: string, index: number) => {
return (
<PanelRow
key={index}
hourLabel={hourLabel}
hoursRow={panel[index]}
rowIndex={index}
/>
)
})}
</View>
</View>
</ScrollView>
</View>
</LinearGradient>
</WhiteContainer>
</Section>
)
}
提前致谢。
解决方案
ScrollView 不会因为子更新而重置滚动位置,无论您是否使用 Redux。您无需尝试使用保存当前滚动位置等变通方法对其进行修补。而是找出您的设置有什么问题
很难说,因为您没有提供实际代码,但我很确定一个或两个 ScrollView 在更新时会重新安装(旧的 ScrollView 已被删除,新的 ScrollView 会在其位置创建并具有自己的滚动位置)。您很可能在渲染函数中声明了新组件,因此 React 每次都会重新安装它们
推荐阅读
- javascript - sinon spy 检查是否调用了 func 总是返回 false 虽然函数
- math - 找到垂直于其他两个点的点的算法
- amazon-web-services - API 网关返回具有特定文件大小的 502 错误
- php - PHP $_GET 用于带加号的参数
- java - 使用 Java 访问嵌套 JSON 对象的最佳方式
- ns2 - ns2中载波侦听阈值的最小值是多少
- string - 定义一个函数,让您查看整数 m 是否是 n 的倍数
- c# - 更改我的 Xamarin GTK# 应用程序的 .NET 框架版本后出现错误 CS0234
- forms - Flutter Desktop - 关注表单中的输入字段
- pandas - Pandas - 根据 Dataframe 的两个后续行查找差异