我正在开发一个反应本机应用程序,其中一个屏幕显示用户列表,另一个屏幕显示消息列表。当用户单击其中一位用户时,他们会转到消息屏幕。在消息屏幕中,如果有新用户加入,则会自动返回到用户屏幕。两个屏幕位于同一堆栈上。当用户上一屏幕的状态发生变化时,如何保持在消息屏幕上?
//_layout.tsx
// a part of code
<Stack.Screen name="home" />
<Stack.Screen name="chatpage" />
在主屏幕中,每个用户都显示为按钮。当新用户加入时,列表更新
const activeSocketUsersList = useSelector((state: RootState) => {
return state.socketReducer.users;
});
const [activeSocketUsers, setActiveSocketUsers] = useState<any>(activeSocketUsersList);
当用户按下按钮时,它会导航到聊天页面
// part of a flatlist with list of buttons
onPress={() => {
// store.dispatch(setUser(item.userID));
router.navigate({
pathname: "/chatpage",
params: {
users: JSON.stringify({
from: socket.id,
to: item.userID,
}),
},
});
}}
>
<Text style={{ color: "#00f" }}>{item.userName}</Text>
在聊天页面,它显示交换的消息列表,以及发送新消息的输入和按钮。
在聊天页面中,如果有新用户加入,则会返回主屏幕以显示更新的用户列表。
如何获取更新的列表,同时让用户保持在聊天页面?
代码在全局
app/_layout.tsx
文件中具有套接字事件侦听器。当新用户加入时,它正在更新全局 redux 存储状态。有一个 useSelector
钩子可以监听新用户,并且显示用户列表的平面列表也会相应更新。
新用户连接和断开连接的监听器从
app/homepage.tsx
移至 app/_layout.tsx
,并且不再更新 redux 状态下的全局用户列表,而是简单地更新用户列表的本地状态。
const onUserConnects = (user: any) => {
// store.dispatch(adduser(user));
setActiveSocketUsers((u: any) => [...u, user]);
};
const onUserDisconnects = (user: any) => {
// delete from active users
// store.dispatch(redUserbyID(user));
setActiveSocketUsers((u: any) =>
[...u].filter((v: any) => v?.userID !== user?.userID)
);
// console.log(user, "disconnects");
};
但是,旧的现有用户是从全局 redux 状态中获取的,并由
app/_layout.tsx
中的全局侦听器进行管理。
所以,即使新用户加入,当前用户在
chatpage
时,也不会中断返回homepage
,并且当用户返回时,他们可以找到新加入的用户。
总而言之,在主页中管理少数相关监听器,并使用
useState
处理本地状态而不是使用 useSelector
处理全局状态解决了我的问题。