Home > Software design >  Cannot read properties of undefined using redux ERROR
Cannot read properties of undefined using redux ERROR

Time:12-01

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}/>
  • Related