React Native Chat App, Flatlist useRef is null - PullRequest
0 голосов
/ 14 апреля 2020

Я создаю приложение чата с React Native, используя Expo, и я использую Flatlist как дочерний элемент KeyboardAvoidingView для визуализации списка сообщений, проблема в том, что я хочу прокрутить страницу вниз при срабатывании клавиатуры

Поэтому я использовал метод Flatlist (scrollToEnd) с ловушкой useRef, и мой код выглядит следующим образом:

const ChatBody = ({ messages }) => {

      const listRef = useRef(null);

      useEffect(() => {
        Keyboard.addListener("keyboardWillShow", () => {
          setTimeout(() => listRef.current.scrollToEnd({ animated: true }), 100);
        });

        return () => Keyboard.removeListener("keyboardWillShow");
      }, []);

      return (
        <FlatList
          ref={listRef}
          keyboardDismissMode="on-drag"
          data={messages}
          keyExtractor={(item) => item.id || String(Math.random())}
          renderItem={({ item }) => <Message {...item} />}
       />
}

Код отлично работает при первом рендеринге, но когда я покидаю экран, возвращаюсь снова и запускаю На клавиатуре я получаю эту ошибку:

TypeError : null in not an object (evaluating 'listRef.current.scrollToEnd')

* Причина, по которой я добавил setTimout, заключалась в том, что scrollToEnd по какой-то причине не работает, когда вызывается событие клавиатуры. добавление setTimeout решило эту проблему.

Дерево компонентов выглядит примерно так:

StackNavigatorScreen => KeyboardAvoidingView => FlatList

Ответы [ 2 ]

0 голосов
/ 15 апреля 2020

Вам нужно передать ваш обработчик событий как второй параметр Keyboard.removeListener. Поскольку вы передаете только первый аргумент, ваш обработчик запускается в любом случае и до того, как ваш ref может быть установлен.

const ChatBody = ({ messages }) => {
    const listRef = useRef(null);

    useEffect(() => {
        Keyboard.addListener("keyboardWillShow", onKeyboardWillShow);

        return () => Keyboard.removeListener("keyboardWillShow", onKeyboardWillShow);
    }, []);

    function onKeyboardWillShow() {
        setTimeout(() => {
            listRef.current.scrollToEnd();
        }, 100);
    }

    return (
        <FlatList
            ref={listRef}
            keyboardDismissMode="on-drag"
            data={messages}
            keyExtractor={(item) => item.id || String(Math.random())}
            renderItem={({ item }) => <Message {...item} />}
        />
    )
}
0 голосов
/ 14 апреля 2020

const listRef = useRef(null); <- эта строка вызывает проблему. </p>

Вам необходимо назначить объект, null в этом случае не может быть помещен туда, поскольку это не объект.

...