React native:在调用另一个与状态相关的操作之前,如何等待设置状态?
React native: how do I wait for a state to be set, before I call another state related operation?
我正在编写一个聊天应用程序。用户可以搜索其他用户,然后按下“消息”按钮。然后我导航到 ChatScreen.js
。如果两个用户一直在互相发送消息,我会相应地设置 chatId
变量。如果他们在我不创建 chatId
之前没有互相发送消息,直到发送了第一条消息。发送第一条消息时,我首先创建新聊天,将其属性(用户 ID、chatId 等)存储在我的数据库中,然后发送第一条消息。问题是我将 chatId
存储为状态变量,当我创建聊天时调用 setChatId(id)
。 setChatId()
不是同步调用,所以当我需要用 sendText(text, chatId);
发送消息时,我的 chatId
是 undefined
,即使我已经创建了聊天并调用了setChatId
.
如何避免这个错误? Ofc,我可以检查 if chatId == undefined
然后调用 sendText(text, id)
,否则调用 sendText(text, chatId)
。有没有 better/neath 方法可以避免 undefined
检查?
这是我的部分代码:
...
import {
createChat,
} from "./actions";
...
function ChatScreen(props) {
...
const [chatId, setChatId] = useState(props.route.params.chatId);
...
const setupChat = async () => {
try {
await createChat(user.id, setChatId);
props.fetchUserChats();
} catch (error) {
console.error("Error creating chat: ", error);
}
};
async function handleSend(messages) {
if (!chatId) {
// creating chat
await setupChat();
}
const text = messages[0].text ? messages[0].text : null;
const imageUrl = messages[0].image ? messages[0].image : null;
const videoUrl = messages[0].video ? messages[0].video : null;
const location = messages[0].location ? messages[0].location : null;
//assuming chatId is already setup but it is not
if (imageUrl) {
sendImage(imageUrl, chatId, setSendImageError);
} else if (location) {
sendLocation(location, chatId, setLocationError);
} else if (videoUrl) {
sendVideo(videoUrl, chatId, setSendImageError);
} else {
sendText(text, chatId);
}
}
...
}
我的 createChat
函数来自 actions.js
文件
export async function createChat(otherUid, setChatId) {
let chatId = firebase.auth().currentUser.uid + "_" + otherUid;
await firebase
.firestore()
.collection("Chats")
.doc(chatId)
.set({
users: [firebase.auth().currentUser.uid, otherUid],
lastMessage: "Send the first message",
lastMessageTimestamp: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("doc ref for creatign new chat: ", chatId);
setChatId(chatId);
})
.catch((error) => {
console.error("Error creating chat: ", error);
});
}
我建议您使用 useRef()
,而不是使用状态变量。这将是您 problem.Eg 以这种方式定义它的一个很好的解决方案
const chatId = useRef(null)
,
那就这样设置吧chatId.current = yourChatId
并以这种方式获得它 chatId.current
。我希望这能解决你的问题
我正在编写一个聊天应用程序。用户可以搜索其他用户,然后按下“消息”按钮。然后我导航到 ChatScreen.js
。如果两个用户一直在互相发送消息,我会相应地设置 chatId
变量。如果他们在我不创建 chatId
之前没有互相发送消息,直到发送了第一条消息。发送第一条消息时,我首先创建新聊天,将其属性(用户 ID、chatId 等)存储在我的数据库中,然后发送第一条消息。问题是我将 chatId
存储为状态变量,当我创建聊天时调用 setChatId(id)
。 setChatId()
不是同步调用,所以当我需要用 sendText(text, chatId);
发送消息时,我的 chatId
是 undefined
,即使我已经创建了聊天并调用了setChatId
.
如何避免这个错误? Ofc,我可以检查 if chatId == undefined
然后调用 sendText(text, id)
,否则调用 sendText(text, chatId)
。有没有 better/neath 方法可以避免 undefined
检查?
这是我的部分代码:
...
import {
createChat,
} from "./actions";
...
function ChatScreen(props) {
...
const [chatId, setChatId] = useState(props.route.params.chatId);
...
const setupChat = async () => {
try {
await createChat(user.id, setChatId);
props.fetchUserChats();
} catch (error) {
console.error("Error creating chat: ", error);
}
};
async function handleSend(messages) {
if (!chatId) {
// creating chat
await setupChat();
}
const text = messages[0].text ? messages[0].text : null;
const imageUrl = messages[0].image ? messages[0].image : null;
const videoUrl = messages[0].video ? messages[0].video : null;
const location = messages[0].location ? messages[0].location : null;
//assuming chatId is already setup but it is not
if (imageUrl) {
sendImage(imageUrl, chatId, setSendImageError);
} else if (location) {
sendLocation(location, chatId, setLocationError);
} else if (videoUrl) {
sendVideo(videoUrl, chatId, setSendImageError);
} else {
sendText(text, chatId);
}
}
...
}
我的 createChat
函数来自 actions.js
文件
export async function createChat(otherUid, setChatId) {
let chatId = firebase.auth().currentUser.uid + "_" + otherUid;
await firebase
.firestore()
.collection("Chats")
.doc(chatId)
.set({
users: [firebase.auth().currentUser.uid, otherUid],
lastMessage: "Send the first message",
lastMessageTimestamp: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("doc ref for creatign new chat: ", chatId);
setChatId(chatId);
})
.catch((error) => {
console.error("Error creating chat: ", error);
});
}
我建议您使用 useRef()
,而不是使用状态变量。这将是您 problem.Eg 以这种方式定义它的一个很好的解决方案
const chatId = useRef(null)
,
那就这样设置吧chatId.current = yourChatId
并以这种方式获得它 chatId.current
。我希望这能解决你的问题