React Native Chat App,Flatlist useRef 为空
React Native Chat App, Flatlist useRef is null
我正在使用 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
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} />}
/>
)
}
我正在使用 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
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} />}
/>
)
}