Reputation: 119
I am using react to build my app and on the post component there are 3 other child components that are been called in a map function while passing the post props.
On the list component when a user clicks on the like button the post tends to reload, and that is not what I want.
This is my post parent component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
class Posts extends Component {
constructor(props) {
super(props)
this.state = {
sidebaropen: false,
test: '',
posts: []
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.post.posts.length > 0) {
this.setState({ posts: nextProps.post.posts })
console.log('updated')
}
}
componentDidMount() {
this.props.getPosts();
socket.on('posts', data => {
console.log("resiving :" + JSON.stringify(data))
if (Object.keys(this.state.posts).length > 0 && Object.keys(data).length >
0) {
this.setState({ posts: [data[0], ...this.state.posts] })
} else {
this.setState({ posts: data })
}
})
socket.on('id', data => {
console.log(data)
})
console.log('mounted post')
}
}
render(){
const { loading } = this.props.post;
const { posts, } = this.state;
let closebtn
let postContent;
if (posts === null || loading) {
postContent = <Spinner />;
} else {
postContent = <PostFeeds posts={ posts } />;
}
if (this.state.sidebaropen) {
closebtn = <button className='close-toggle-btn' onClick =
{ this.closetoggleclickhandle } />
}
return (
<div className= "post_wrapper" >
<Postsidebar show={ this.state.sidebaropen } />
< div className = "" >
{ postContent }
< /div>
{ closebtn }
<TiPlus className='creat-post-toggle-btn icons' onClick =
{ this.toggleclickhandle } />
</div>
)
}
}
Posts.propTypes = {
getPosts: PropTypes.func.isRequired,
post: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
post: state.post
})
export default connect(mapStateToProps, { getPosts })(Posts);
and this is the first child component
import React, { Component } from 'react';
import PostItem from './PostItem';
class PostFeeds extends Component {
componentDidMount() {
//this.setState({ test : 'mounted'})
console.log('mounted feed')
}
render() {
const { posts } = this.props;
//console.log(posts)
return posts.map(post => <PostItem key={ post._id } post = { post } />);
}
}
postItem.js its i little kind of rough
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { deletePost, addLike, removeLike, bookmark } from "../../actions/postsActions";
import Postimg from './Postimg';
import { MdBookmarkBorder ,/**MdBookmark */} from "react-icons/md";
import {AiFillDislike, AiOutlineLike, AiFillDownSquare} from 'react-icons/ai'
import { TiHeartOutline, TiHeartFullOutline, TiMessage, TiDelete } from "react-icons/ti";
class PostItem extends Component {
onDeleteClick(id){
this.props.deletePost(id);
}
componentWillMount() {
console.log( 'mounted item')
//console.log(window.scrollTo(0, localStorage.getItem('scrollpossition')))
}
onLikeClick(id){
this.props.addLike(id);
// window.scrollTo(0, localStorage.getItem('scrollpossition'))
window.location.href = '/feed'
}
onUnlikeClick(id){
this.props.removeLike(id);
// window.scrollTo(0, localStorage.getItem('scrollpossition'))
window.location.href = '/feed'
}
findUserLike(likes) {
const { auth } = this.props;
if(likes.length > 0){
if(likes.filter(like => like.user === auth.user.id).length > 0) {
return true;
} else {
return false;
}
}
}
findUserDislike(dislikes) {
const { auth } = this.props;
if(dislikes.length > 0){
if(dislikes.filter(dislike => dislike.user === auth.user.id).length > 0) {
return true;
} else {
return false;
}
}
}
onBookmark (id){
this.props.bookmark(id)
}
render() {
const { post, auth, showActions } = this.props;
let ifAlreadyliked;
let ifAlreadydisliked;
let postimg;
let postText;
let profileimg
let topic = ''
if(post.user)
{
if(post.user.profileImageData){
profileimg = <Link to={`/profile/${post.profile.handle}`}><img src={post.profile.profileImageData} alt='' /></Link>
}else{
profileimg = <img src='/assets/images/user-4.png' alt='pip' />
}
if(this.findUserLike(post.likes)){
ifAlreadyliked = <TiHeartFullOutline className= 'icons like-color'/>
}else{
ifAlreadyliked = <TiHeartOutline className= 'icons'/>
}
if(this.findUserDislike(post.dislikes)){
ifAlreadydisliked = <AiFillDislike className= 'icons yellow'/>
}else{
ifAlreadydisliked = <AiOutlineLike className= 'icons' onClick={this.onUnlikeClick.bind(this, post._id)}/>
}
}
if(post.Topic){
topic = <div className= ''><small><b style={{color:'#ff8d00'}}>< AiFillDownSquare />{post.Topic}</b></small></div>
}
if(post.postImageData !== '' && post.postImageData !== null && post.postImageData !== undefined)
{
postimg = <Postimg imageSrc = {post.postImageData} imgAlt = {''}/>
}
if(post.text !== '' || post.text === null)
{
postText = <div className='feed_text'>{post.text}</div>
}
return (
<div className="feed_card">
<div className="feed_header">
<div className="feed-profile-img">{profileimg}</div>
<div className="feed-handle-text">{post.name}</div>
<div className='v-spacer'/>
<div className="time-stamp"><small>{new Date (post.date).toLocaleString ('en-US', {hour: 'numeric', hour12: true, minute: 'numeric', month: 'long', day: 'numeric' } )} </small></div>
</div>
<div className="feed-body-container">
<div>
{topic}
{postimg}
{postText}
<div className='mini_feed_footer'>
<small>{post.likes.length} likes. {post.comments.length} comments. {post.dislikes.length} dislikes.</small>
</div>
{ showActions ? (
<div className='feed_footer'>
<div onClick={this.onLikeClick.bind(this, post._id)} type="button" className="btn btn-light mr-1">
<div className='feed-icon-mini-container'>
{ifAlreadyliked}
</div>
</div>
<div className='spacer'/>
{ifAlreadydisliked}
<div className='spacer'/>
<Link to={`/post/${post._id}`} className='header-brand'>
<TiMessage className='icons'/>
</Link>
<div className='spacer'/>
{ post.user === auth.user.id ? (
<TiDelete
onClick={this.onDeleteClick.bind(this, post._id)}
className="icons red"
/>
) : <MdBookmarkBorder
onClick={this.onBookmark.bind(this, post._id)}
className="icons blue"
/> }
</div>) : null}
</div>
</div>
</div>
);
}
}
PostItem.defaultProps = {
showActions: true
}
PostItem.propTypes = {
post: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired,
deletePost: PropTypes.func.isRequired,
addLike:PropTypes.func.isRequired,
removeLike:PropTypes.func.isRequired,
bookmark:PropTypes.func.isRequired
};
const mapStateToProps = state => ({
auth: state.auth
})
export default connect(mapStateToProps, {deletePost, addLike,bookmark, removeLike})(PostItem);
Upvotes: 0
Views: 230
Reputation: 1801
Don't use window object for navigation (Major) as this causes reload. Make your handlers arrow functions (minor).
onLikeClick = id => {
this.props.addLike(id);
// window.scrollTo(0, localStorage.getItem('scrollpossition'))
this.props.history.push("/feed");
};
onUnlikeClick = id => {
this.props.removeLike(id);
// window.scrollTo(0, localStorage.getItem('scrollpossition'))
this.props.history.push("/feed");
};
Also if /feed
is the same page then remove it all together, no need for it.
Upvotes: 1