Error imageThe error specifically points to:
dispatch({
type: SET_POSTS,
payload: res.data
})
Below is my func code:
export const getPosts = () => dispatch => {
dispatch({ type: LOADING_DATA })
axios.get('/posts')
.then(res => {
dispatch({
type: SET_POSTS,
payload: res.data
})
})
.catch(err => {
dispatch({
type: SET_POSTS,
payload: []
})
})
};
I checked for imports, console.log(res) and everything seems fine, but the error always points to dispatch()
Edit: After tracing the code with redux dev tools I found out that the payload for SET_POSTS
kept changing from payload:[{...}]
to undefined. Below I attached the code for my reducer. I still don't know what the problem is.
import { SET_POSTS, LIKE_POST, UNLIKE_POST, LOADING_DATA } from '../types';
const initialState = {
posts: [],
post: {},
loading: false,
};
export default function (state = initialState, action) {
switch (action.type) {
case LOADING_DATA:
return {
...state,
loading: true
};
case SET_POSTS:
return {
...state,
posts: action.payload,
loading: false,
};
case LIKE_POST:
case UNLIKE_POST:
var index = state.posts.findIndex((post) => post.postId === action.payload.postId);
state.posts[index] = action.payload;
// conditional from github
if (state.post.postId === action.payload.postId) {
state.post = action.payload;
}
return {
...state
};
default:
return state;
}
}
Here is where the getPosts() function is been rendered:
import { getPosts } from '../redux/actions/dataActions';
class home extends Component {
componentDidMount() {
this.props.getPosts();
}
render() {
const { posts, loading } = this.props.data;
let recentPostsMarkup = !loading ? (
posts.map(post => <Post key={post.postId} post={post} />)
) : (<p>loading...</p>);
return (
<Grid container spacing={5}>
<Grid item sm={8} xs={12}>
{recentPostsMarkup}
</Grid>
<Grid item sm={4} xs={12}>
<Profile />
</Grid>
</Grid>
);
home.propTypes = {
getPosts: PropTypes.func.isRequired,
data: PropTypes.object.isRequired,
}
const mapStateToProps = state => ({
data: state.data
});
export default connect(mapStateToProps, { getPosts })(home);
This is the Post.js
file where the post
prop is being passed in the home.js
file.
class Post extends Component {
likedPost = () => {
if (this.props.user.likes && this.props.user.likes.find(
like => like.postId === this.props.post.postId)
) return true;
else return false;
};
likePost = () => {
this.props.likePost(this.props.post.postId);
}
unlikePost = () => {
this.props.unlikePost(this.props.post.postId);
}
render() {
dayjs.extend(relativeTime);
const {
classes,
post: { body, createdAt, userImage, userHandle, postId, likeCount, commentCount },
user: {
authenticated
}
} = this.props;
const likeButton = !authenticated ? (
<MyButton tip="Like">
<Link to="/login">
<FavoriteBorder color="primary"/>
</Link>
</MyButton>
) : (
this.likedPost() ? (
<MyButton tip="Undo like" onClick={this.unlikePost}>
<FavoriteIcon color="primary"/>
</MyButton>
): (
<MyButton tip="Like" onClick={this.likePost}>
<FavoriteBorder color="primary"/>
</MyButton>
)
)
return (
<Card className={classes.card}>
<CardMedia
image={userImage}
title="Profile Image" className={classes.image} />
<CardContent className={classes.content}>
<Typography
variant="h5"
component={Link}
to={`/users/${userHandle}`}
color="primary">
{userHandle}
</Typography>
<Typography variant="body2" color="textSecondary">
{dayjs(createdAt).fromNow()}
</Typography>
<Typography variant="body1">
{body}
</Typography>
{likeButton}
<span>{likeCount} Likes</span>
<MyButton tip="comments">
<ChatIcon color="primary" />
</MyButton>
<span>{commentCount} comments</span>
</CardContent>
</Card>
)
}
};
Ciao, this is a well known issue in React. Please, check this guide (even if is made for React Native). In brief, your problem is related on how you are importing your component, and is not related on how you are dispatching your data.