Two components using the same component

Viewed 246

I'm trying to avoid code duplication in my project so I decided to create a component which two other components can use, but it doesn't seem to work. Does it have anything to do with the usage of hooks (useEffect) or it doesn't matter at all? This is the code:

reusable component: Posts.js

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { makeStyles } from "@material-ui/core/styles";
import CircularProgress from "@material-ui/core/CircularProgress";
import ErrorPage from "../../pages/ErrorPage";
import Post from "./Post";

const useStyles = makeStyles({
  root: {
    margin: "5em",
    textAlign: "center",
  },
  loading: {
    margin: "0 auto",
    marginTop: "50px",
  },
});

export const Posts = ({ action, postsType }) => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const { token } = useSelector((state) => state.auth);

  useEffect(() => {
    dispatch(action(token));
  }, []);

  const { posts, loading, fetched, error } = useSelector(
    (state) => state.posts[postsType]
  );

  return (
    <div className={classes.root}>
      {loading && (
        <CircularProgress
          className={classes.loading}
          size="200px"
          thickness="1"
        />
      )}
      {fetched && posts.map((post) => <Post postData={post} />)}
      {error && <ErrorPage />}
    </div>
  );
};

Components using Posts.js :

import React from "react";
import { fetchAllPostsByUserId } from "../redux/actions/postsActions";
import { Posts } from "../components/sharedComponents/Posts";

const UserPostsPage = () => (
  <Posts action={fetchAllPostsByUserId} postsType="userPosts" />
);

export default UserPostsPage;

import React from "react";
import { fetchRecommendedPosts } from "../redux/actions/postsActions";
import { Posts } from "../components/sharedComponents/Posts";

const RecommendedUserPostsPage = () => (
  <Posts action={fetchRecommendedPosts} postsType="recommendedPosts" />
);
export default RecommendedUserPostsPage;

this is the redux store state:

const initialState = {
  isPostCreated: false,
  mainPosts: {
    posts: [],
    loading: false,
    fetched: false,
    error: false,
  },
  userPosts: {
    posts: [],
    loading: false,
    fetched: false,
    error: false,
  },
  recommendedPosts: {
    posts: [],
    loading: false,
    fetched: false,
    error: false,
  },
  trendingPosts: {
    posts: [],
    loading: false,
    fetched: false,
    error: false,
  },
};
``
2 Answers

Your state structure does not have posts.

It seems you have a mistake in accessing the data.

Please, try this

const { posts, loading, fetched, error } = useSelector(
    (state) => state[postsType]
  );

your selector is retrieving wrong results, that's why i asked you if these properties were filled correctly. This should work:

  const { posts, loading, fetched, error } = useSelector(
    (state) => state[postsType]
  );
Related