I cannot figure out how to access this Promise object. How to map this promise? And why my async/await function is returning a promise and not a result object? Any feedback appreciated.
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(2)
0: "hey"
1: "bye"
length: 2[[Prototype]]: Array(0)
import { io } from "socket.io-client";
import { useState, useEffect } from "react";
function App() {
const [text, setText] = useState("");
const [socket, setSocket] = useState();
const [chat, setChat] = useState([]);
useEffect(() => {...}, []);
***//getting previous chat for new users.***
useEffect(async () => {
let mounted = true;
const response = await fetch("http://localhost:4000/main_chat").then(
(res) => {
if (mounted) {
setChat(res.json());
}
}
);
return () => (mounted = false);
}, []);
useEffect(() => {...},[socket]);
const handleClick = () => {
socket.emit("sentFromClient", text);
};
return (
<div>
<ul>{console.log(chat)}</ul>
<input value={text} onChange={(e) => setText(e.target.value)}></input>
<button onClick={() => handleClick()}>enter</button>
</div>
);
}
export default App;
CodePudding user response:
fetch
returns a Promise, which you wait for, but then res.json()
returns another Promise, which you don't wait for. So that Promise is passed to setChat
and becomes the value of chat
.
You're also mixing up await
and .then
, which do the same thing, so you should probably only use one or the other.
With await
:
const response = await fetch(...)
const json = await response.json()
setChat(json)
With .then
:
fetch(...)
.then(response => {
return response.json()
})
.then(json => {
setChat(json)
})
Finally, you're right to check if you're still mounted before calling setChat
, but passing an async function to useEffect
won't work because you need to return the cleanup function (() => (mounted = false)
), and async functions return Promises. So:
useEffect(() => {
let mounted = true
const getChat = async () => {
await whatever...
if (mounted) setChat(something)
}
getChat()
return () => (mounted = false)
})
Or
useEffect(() => {
let mounted = true
fetch(...).then(chat => {
if (mounted) setChat(chat)
})
return () => (mounted = false)
})
CodePudding user response:
You are using both .then()
and async\await
which is a bit confusing.
Maybe you should start by removingconsole.log()
from the returned JSX expression.
Then, inside your useEffect hook, update it to this
useEffect(async () => {
let mounted = true;
const response = await fetch("http://localhost:4000/main_chat")
if (mounted) {
// consol.log(response) here should give you the value returned by the API
setChat(response);
}
// Not sure why are you returning this function definition
return () => (mounted = false);
}, []);