0

enter image description here

before adding the map function i was getting the state enter image description here

after adding map function i get.

enter image description here

I am not able to pinpoint the location of the problem.saw many posts on stackoverflow but none solved my probem

import React,{Fragment,useEffect} from 'react'
import PropTypes from 'prop-types'
import PostItem from './PostItem'
import {connect} from 'react-redux'
import {getPosts} from '../../actions/post'
import Spinner from '../layout/spinner'


const Posts = ({ getPosts, post: { posts, loading } })=>{
useEffect(()=>{
    getPosts();
},[getPosts])

return loading ?<Spinner/>:(
    <Fragment>
      <h1 className="large text-primary">Posts</h1>
      <p className="lead">
          <i className="fas fa-user"></i>Welcome to the community
      </p>
      {/* PostForm*/}
      <div className="posts">
           {
               posts.map((post)=>{
                   return <PostItem key={post._id} post={post} />
               })
           }
      </div>

    </Fragment>
)
}


Posts.propTypes={
 getPosts:PropTypes.func.isRequired,
 post:PropTypes.object.isRequired,
}

const mapStateToProps=state=>({
  post:state.post
})

export default connect(mapStateToProps,{getPosts})(Posts)
1
  • first console your posts to check that you r getting values or not Commented Dec 6, 2019 at 5:45

4 Answers 4

2

You must check posts first before calling map function to prevent calling it before the data being passed to the props. Like this posts && posts.map(() => {})

import React, { Fragment, useEffect } from "react";
import PropTypes from "prop-types";
import PostItem from "./PostItem";
import { connect } from "react-redux";
import { getPosts } from "../../actions/post";
import Spinner from "../layout/spinner";

const Posts = ({ getPosts, post: { posts, loading } }) => {
  useEffect(
    () => {
      getPosts();
    },
    [getPosts]
  );

  return loading ? (
    <Spinner />
  ) : (
    <Fragment>
      <h1 className="large text-primary">Posts</h1>
      <p className="lead">
        <i className="fas fa-user" />Welcome to the community
      </p>
      {/* PostForm*/}
      <div className="posts">
        {posts &&
          posts.map(post => {
            return <PostItem key={post._id} post={post} />;
          })}
      </div>
    </Fragment>
  );
};

Posts.propTypes = {
  getPosts: PropTypes.func.isRequired,
  post: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  post: state.post
});
Sign up to request clarification or add additional context in comments.

2 Comments

Its working for me but I am not conviced.I am following a tutorial in udemy and my instructor is not using posts && .how is that working for him ????
@SwagathShetty maybe he did is the posts props is not empty before calling the <Posts> component so you don't need to check it anymore inside the component. For example you ParentComponent.js where you use the <Posts /> component, { post && post.length && <Posts post={post} /> }
1

You need to use condition to check values before mapping to avoid errors.

1- {posts?posts.map():null}

2- {posts && posts.map()}

 <Fragment>
          <h1 className="large text-primary">Posts</h1>
          <p className="lead">
              <i className="fas fa-user"></i>Welcome to the community
          </p>
          {/* PostForm*/}
          <div className="posts">
               {
                   posts?posts.map((post)=>{
                       return <PostItem key={post._id} post={post} />
                   }):null
               }
          </div>

        </Fragment>

or

<Fragment>
      <h1 className="large text-primary">Posts</h1>
      <p className="lead">
          <i className="fas fa-user"></i>Welcome to the community
      </p>
      {/* PostForm*/}
      <div className="posts">
           {
               posts && posts.map((post)=>{
                   return <PostItem key={post._id} post={post} />
               })
           }
      </div>

    </Fragment>

3 Comments

It's posts?.map by the way. I don't think posts?posts.map is valid
@iamdevlinph it's ternary condition
Ah my bad. Didn't notice the : null at the bottom. I thought you were doing an optional chaining
1

You can do something like the below code.

import React,{Fragment,useEffect} from 'react'
import PropTypes from 'prop-types'
import PostItem from './PostItem'
import {connect} from 'react-redux'
import {getPosts} from '../../actions/post'
import Spinner from '../layout/spinner'


const Posts = ({ getPosts, post: { posts, loading } })=>{
useEffect(()=>{
    getPosts();
},[getPosts])

return loading ?<Spinner/>:(
    <Fragment>
      <h1 className="large text-primary">Posts</h1>
      <p className="lead">
          <i className="fas fa-user"></i>Welcome to the community
      </p>
      {/* PostForm*/}
      {posts.length ? 
      <div className="posts">
           {
               posts.map((post)=>{
                   return <PostItem key={post._id} post={post} />
               })
           }
      </div> : }

    </Fragment>
)
}


Posts.propTypes={
 getPosts:PropTypes.func.isRequired,
 post:PropTypes.object.isRequired,
}

const mapStateToProps=state=>({
  post:state.post
})

export default connect(mapStateToProps,{getPosts})(Posts)

Comments

0

const Posts = ({ getPosts, post: { posts, loading } })=>{
useEffect(()=>{
    getPosts();
},[getPosts])

return loading ?<Spinner/>:(
    <Fragment>
      <h1 className="large text-primary">Posts</h1>
      <p className="lead">
          <i className="fas fa-user"></i>Welcome to the community
      </p>
      {/* PostForm*/}
      {posts.length ? 
      <div className="posts">
           {
               (posts || []).map((post)=>{
                   return <PostItem key={post._id} post={post} />
               })
           }
      </div> : }

    </Fragment>
)
}


Posts.propTypes={
 getPosts:PropTypes.func.isRequired,
 post:PropTypes.object.isRequired,
}

const mapStateToProps=state=>({
  post:state.post || [],
})

export default connect(mapStateToProps,{getPosts})(Posts)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.