I am writing a chat app. Users can search for other users, and then press the "Message" button. Then I navigate to ChatScreen.js
. If both users have been messaging each other, I set the chatId
variable accordingly. If they have not messaged each other before I dont create chatId
, until the ery first message has been sent. When the first message is sent, I first, create new chat, store its properties (user ids, chatId, etc) in my db and then I sent the first message. The problem is that I store chatId
as a state variable, and when I create the chat I call setChatId(id)
. setChatId()
is not synchronous call, so by the time when I need to send message with sendText(text, chatId);
my chatId
is undefined
even though I have already created a chat and I have called setChatId
.
How can I avoid this error? Ofc, I can check if chatId == undefined
then calling sendText(text, id)
, otherwise calling sendText(text, chatId)
. Is there a better/neath way to avoid the undefined
check?
Here is part of my code:
...
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);
}
}
...
}
My createChat
function from actions.js
file
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);
});
}
CodePudding user response:
Instead of using a state variable, I would advise you to use useRef()
. This would be a good solution to your problem.Eg Define it this way
const chatId = useRef(null)
,
then set it this way chatId.current = yourChatId
and get it this way chatId.current
. I hope this solves your problem