I am having an error when refreshing my browser.
Uncaught TypeError: Cannot read properties of undefined (reading 'title')
And it keeps on repeating for all of my states (title
, content
, id
) until I delete them from code down below... And also it works fine until I refresh the page.
import React, { FC, useEffect } from 'react';
import { useLocation, useParams } from 'react-router-dom';
import AddComment from 'src/components/ui/AddComment/AddComment';
import CommentSection from 'src/components/ui/CommentSection/CommentSection';
import PostContent from 'src/components/ui/PostContent/PostContent';
import PostHeader from 'src/components/ui/PostHeader/PostHeader';
import {useAppSelector } from 'src/store/app/hooks';
const Post: FC = () => {
const { id } = useParams();
const { posts } = useAppSelector((state) => state.post);
return (
<div>
<PostHeader
header={<h2>{posts.find(p => p.id === parseInt(id)).title}</h2>}
>
<div>
{posts.find(p => p.id === parseInt(id)).content}
</div>
</PostHeader>
<PostContent
content={<div>{posts.find(p => p.id === parseInt(id)).content}</div>}
/>
<AddComment id={id} />
<CommentSection id={id} />
</div>
)
};
export default Post;
I also want to stop posts from dissapearing after refresh.
CodePudding user response:
Issue
The basic issue is that Array.prototype.find
returns undefined
when there is no match. The code should account for this and handle not having a matching post object gracefully.
Solution
I suggest only searching the posts
array once and saving the result. If the result is truthy then access the properties, otherwise render null
or some other fallback UI.
Example:
const Post : FC = () => {
const { id } = useParams();
const { posts } = useAppSelector((state) => state.post);
const post = posts.find(p => String(p.id) === id);
if (!post) {
return <div>No post here.</div>;
}
return (
<div>
<PostHeader header={<h2>{post.title}</h2>}>
<div>{post.content}</div>
</PostHeader>
<PostContent content={<div>{post.content}</div>} />
<AddComment id={id} />
<CommentSection id={id} />
</div>
)
};
CodePudding user response:
I don't know the type definitions, but this has to do that your are trying to get a property from posts.find
. If posts find doesn't match —which won't do when loading the state— that will fail.
Try adding nullisch coalescing opertators to all your Array.find
methods
<PostHeader header={<h2>{posts.find(p => p.id === parseInt(id))?.title}</h2>}>
<div>{posts.find(p => p.id === parseInt(id))?.content}</div>
</PostHeader>
<PostContent content={<div>{posts.find(p => p.id === parseInt(id))?.content}</div>}/>
<AddComment id = {id} />
<CommentSection id = {id}/>