React native ScrollView при ререндаре возвращается в самый верх?

При ререндаре/изменения состояния 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
  • Вопрос задан
  • 65 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
19 апр. 2024, в 03:01
1000 руб./за проект
18 апр. 2024, в 21:56
2000 руб./за проект
18 апр. 2024, в 21:00
150 руб./за проект