Reputation: 13
I'm new to ReactJS and I'm now trying to do an interactive comments section (taken from frontendmentor.io), but the App component just doesn't show what it's supposed to show
This is my App
component:
function App() {
const [data, setData] = useState([]);
useEffect(() => {
const getComm = async () => {
await fetchData();
};
getComm();
}, []);
console.log(data);
const fetchData = async () => {
const res = await fetch("db.json").then(async function (response) {
const comm = await response.json();
setData(comm);
return comm;
});
};
return (
<Fragment>
{data.length > 0 ? <Comments data={data} /> : "No Comments to Show"}
</Fragment>
);
}
export default App;
The console.log(data)
logs two times:
If I force the App
to print the Comments
it just says that cannot map through an undefined variable
This is my Comments
component:
function Comments({ data }) {
return (
<div>
{data.map((c) => (
<Comment key={c.id} />
))}
</div>
);
}
export default Comments;
I'm wondering why the page still displays No Comments to Show
even if the log is correct
Upvotes: 1
Views: 1824
Reputation: 2018
@Cristian-Irimiea Have right about response get from fetch. Response is an a object and can't be iterate. You need to store in state the comments
from response
But you have multiple errors:
fetchData
looks bad.// Your function
const fetchData = async () => {
const res = await fetch("db.json").then(async function (response) {
const comm = await response.json();
setData(comm);
return comm;
});
};
// How can refactor
// fetchData function have responsibility to only fetch data and return a json
const fetchData = async () => {
const response = await fetch("./db.json");
const body = await response.json();
return body;
};
useEffect(() => {
// here we use .then to get promise response and update state
fetchData().then((response) => setData(response.comments));
}, []);
Upvotes: 1
Reputation: 111
The initial state of your data
is an array.
After you fetch your data from the response you get an object. Changing state types is not a good practice. You should keep your data
state as an array or as an object.
Considering you will keep it as an array, you need use an array inside of setData
.
Ex.
comm && Array.isArray(comm.comments) && setData(comm.comments);
As for your Comments
component you should consider expecting an array not an object.
Ex.
function Comments(data) {
return (
<div>
{data.map((c) => (
<Comment key={c.id} />
))}
</div>
);
}
export default Comments;
Upvotes: 1