React Native Chat App,Flatlist useRef 为空

React Native Chat App, Flatlist useRef is null

我正在使用 Expo 使用 React Native 构建一个聊天应用程序,我使用 Flatlist 作为 KeyboardAvoidingView 的子项来呈现消息列表,问题是我想在触发键盘时滚动到底部

所以我使用带有 useRef 挂钩的 Flatlist 方法 ( s​​crollToEnd ),我的代码如下所示:

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

const listRef = useRef(null); <-- 这一行是导致问题的原因。

您需要分配一个对象,null 在这种情况下不能放在那里,因为它不是对象。

您需要将事件处理程序作为第二个参数传递给 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} />}
        />
    )
}