【问题标题】:React Native Chat App, Flatlist useRef is nullReact Native 聊天应用,Flatlist useRef 为空
【发布时间】:2020-04-14 19:08:54
【问题描述】:

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

所以我使用了带有 useRef 钩子的 Flatlist 方法 (scrollToEnd),我的代码如下所示:

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

【问题讨论】:

    标签: react-native react-hooks chat react-native-flatlist


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      const listRef = useRef(null);

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

      【讨论】:

      • 这根本不是真的。 useRef 采用初始值,稍后在渲染期间通过 OP 正在使用的 refprop 设置。
      猜你喜欢
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 2018-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多