При ререндаре/изменения состояния redux у меня всегда ScrollView, возвращается на самый верх, как это возможно исправить?
Вот файл в котором есть ScrollView:
function TodayView() {
const dispatch = useDispatch()
const today = moment().format('DD-MM-YYYY').valueOf();
const todayDate = moment(today, 'DD-MM-YYYY').valueOf();
const todoes = useSelector(state => state.todo.todoes)
const todoesLoading = useSelector(state => state.todo.todoesLoading)
const d = new Date();
const n = d.getDay();
// let todoesToday =
console.log(todoesLoading)
const todoesToday = useMemo(() => {
return todoes.filter(todo =>
(moment(todo.date, 'DD-MM-YYYY').valueOf() === todayDate
&& moment(todo.date, 'DD-MM-YYYY').valueOf() !== NaN)
|| (moment(todo.date, 'DD-MM-YYYY').valueOf() <= todayDate
&& todo.deysWeek.indexOf(n) !== -1)
|| (todo.date === "" && todo.deysWeek.indexOf(n) !== -1))
}, [todoes])
useEffect(() => {
console.log("render1")
// dispatch(getTodoes())
// console.log(scroll.current)
}, [])
const styles = StyleSheet.create({
container: {
flex: 1,
width: "100%",
justifyContent: 'center', //Centered vertically
alignItems: 'center', // Centered horizontally
},
text: {
color: "#808080"
},
fab: {
position: 'absolute',
margin: 0,
right: 0,
bottom: 0,
},
block: {
marginBottom: 85,
},
});
return (
<>
{(todoesLoading) ? (
<View style={styles.container}>
<ActivityIndicator />
</View>
) : (
<>
{todoesToday.length !== 0 &&
<Animated.ScrollView
scrollEventThrottle={1}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: new Animated.Value(0) } } }],
{ useNativeDriver: true } // <-- Add this
)} >
<View style={styles.block}>
<BlockTodoTodey />
</View>
</Animated.ScrollView>
}
{todoesToday.length === 0 &&
<View style={styles.container}>
<Text style={styles.text}>{I18n.t("noTodayTodo")}</Text>
</View>
}
</>
)}
</>
)
}
export default React.memo(TodayView);
BlockTodoTodey:
import React, { useCallback, useEffect, useMemo } from 'react';
import { StyleSheet} from 'react-native';
import { useSelector } from 'react-redux';
import moment from 'moment';
import I18n from '../../libs/i18n'
import ItemTodo from './ItemTodo';
function BlockTodoTodey() {
const today = moment().format('DD-MM-YYYY').valueOf();
const todayDate = moment(today, 'DD-MM-YYYY').valueOf();
const todoes = useSelector(state => state.todo.todoes)
const lists = useSelector(state => state.list)
const d = new Date();
const n = d.getDay();
const sortTodoesToday = (todoesToday) => {
todoesToday.sort((a, b) => parseTime(a.time) > parseTime(b.time) ? -1 : 1);
todoesToday.sort((a, b) => !a.time ? -1 : 1);
todoesToday.sort((a, b) => a.time && now > parseTime(a.time) ? 1 : -1);
todoesToday.sort((a, b) => a.ready < b.ready ? -1 : 1);
return todoesToday
}
// let todoesToday =
let todoesToday = todoes.filter(todo =>
(moment(todo.date, 'DD-MM-YYYY').valueOf() === todayDate
&& moment(todo.date, 'DD-MM-YYYY').valueOf() !== NaN)
|| (moment(todo.date, 'DD-MM-YYYY').valueOf() <= todayDate
&& todo.deysWeek.indexOf(n) !== -1)
|| (todo.date === "" && todo.deysWeek.indexOf(n) !== -1))
const now = moment();
const parseTime = timeString => +moment(timeString, 'HH:mm')
useEffect(() => {
console.log("render2")
// console.log(scroll.current)
}, [])
const getNameList = (todo) => {
if(todo.list === "0") {
return I18n.t("otherList")
}
const list = lists.filter(el => el.id === todo.list)[0]
return list.name
}
const renderTodoes = useMemo(() => {
todoesToday = sortTodoesToday(todoesToday)
// console.log(todoesToday)
return todoesToday.map((item) => {
const index = todoes.findIndex(el => el.id === item.id)
// console.log(index)
let description = getNameList(item)
return <ItemTodo key={item.id} id={item.id} index={index} description={description} />
})
}, [todoes])
return (
<>
{renderTodoes}
</>
)
}
export default React.memo(BlockTodoTodey);
ItemTodo:
import React, { useState } from 'react';
import { View } from 'react-native';
import { Divider, IconButton, List } from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import moment from 'moment';
import { MaterialCommunityIcons, FontAwesome } from "../../libs/icons";
import statLib from '../../libs/stat';
import { ColorIcon } from '../../libs/theme';
import { getStat } from '../../redux/actions/statActions';
import { cancelTodo, readyTodo } from '../../redux/actions/todoActions';
import settingLib from '../../libs/settingLib';
import I18n from '../../libs/i18n'
import { useNavigation } from '@react-navigation/native';
import { openWinDelTodo } from '../../redux/actions/appActions';
const ItemTodo = ({id, index, description}) => {
const dispatch = useDispatch()
const todo = useSelector(state => state.todo.todoes.filter(el => el.id === id))[0]
const theme = useSelector(state => state.app.theme)
const typeTheme = settingLib.getTypeTheme(theme);
const navigation = useNavigation()
const clickChackBox = (id, index, ready) => {
if (!ready) {
dispatch(readyTodo(index, id))
} else {
dispatch(cancelTodo(index, id))
}
statLib.chackTodayStat()
dispatch(getStat())
}
const parseTime = timeString => +moment(timeString, 'HH:mm')
return (
<>
<List.Item
key={todo.id}
titleStyle={(+parseTime(todo.time) <= +parseTime(moment().format('HH:mm')) || todo.ready === true) ? {"color": ColorIcon.chackboxReady(typeTheme)} : {"color": ColorIcon.chackboxNoReady(typeTheme)}}
descriptionStyle={{"color": ColorIcon.descriptionColor(typeTheme, todo.ready, +parseTime(todo.time) <= +parseTime(moment().format('HH:mm')))}}
title={todo.title}
description={((todo.time !== "") ? moment(todo.time, "HH:mm").format(I18n.t("formatTime")) : "--:--") + " (" + description + ")"}
onPress={() => navigation.navigate('Todo', {title: todo.title, todoId: todo.id, id: index, type: "Todo"})}
left={props => <IconButton
{...props}
onPress={() => clickChackBox(todo.id, index, todo.ready)}
icon={
() => <MaterialCommunityIcons
name={(todo.ready === true) ? "checkbox-marked-circle-outline" : "checkbox-blank-circle-outline"}
size={30}
color={(+parseTime(todo.time) <= +parseTime(moment().format('HH:mm')) || todo.ready === true) ? ColorIcon.chackboxReady(typeTheme) : ColorIcon.chackboxNoReady(typeTheme)} />}
/>}
right={props => <IconButton
{...props}
onPress={() => dispatch(openWinDelTodo({title: todo.title, todoId: todo.id, index: index}))}
icon={() => <FontAwesome name="trash" size={25} color={(+parseTime(todo.time) <= +parseTime(moment().format('HH:mm')) || todo.ready === true) ? ColorIcon.treshReady(typeTheme) : "#ff221e"} />}
/>}
/>
<Divider />
</>
)
}
export default ItemTodo