У меня проблема (вероятно, это то, что я игнорирую в цикле рендеринга) с сохранением позиции двух разных видов прокрутки при обновлении некоторых из его дочерних компонентов.
У меня есть иерархия представлений, которая похожа на:
<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>
Один из возможных подходов к решению этой проблемы - иметь механизм, который позволяет мне сохранять позицию прокрутки перед обновлением. Но это сильно усложнит коммуникацию между компонентами, et c. Кстати, обновление статуса ячейки осуществляется через Redux.
Было бы здорово, если бы кто-нибудь из вас пролил свет на это.
---- ОБНОВЛЕНИЕ 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>
)
}
Заранее спасибо.