Redux устанавливает повторяющиеся значения для всех элементов в отображаемом массиве - PullRequest
0 голосов
/ 23 апреля 2019

У меня проблема с избыточностью, не добавляющей правильные значения для записи.

TLDR: Как я могу сказать, что приёмник получит количество лайков только для этого конкретного post.id. Вместо установки редукции все лайки к значению лайков для первого поста.

следующий код получает количество лайков в каждом сообщении.

export const getLikeCount = (id) => {
    return (dispatch, getState) => {
        return Axios.get(`/api/posts/likes/count/${id}`)
            .then( (res) => {
                 const data = res.data
                 console.log(data); // logs like counts for all posts
                 dispatch({type: GET_LIKES_COUNT, data})
             })

    }
}

тогда он вызывается на редукторе вот так ..

примечание: console.log (action.data) распечатывает значения, подобные этим. Это количество лайков для каждого сообщения, например, пост 1 содержит 12 лайков, а пост 2 содержит 2 лайка.

enter image description here

import {  ADD_LIKE, GET_LIKES_COUNTT} from '../actions/';

const initialState = {
    post: [],
    postError: null,
    posts:[],
    isEditing:false,
    isEditingId:null,
    likes:0,
    postId:null
}

export default (state = initialState, action) => {
      .....
      case GET_LIKES_COUNT:
          // console.log(action.data)
           return({
              ...state,
              likes:action.data
           })
     case ADD_LIKE:
        console.log(action.id) // renders post id which is 2
        console.log(state.posts) // logs posts array 
        return {
        ...state,
        posts: state.posts.map(post => {
          if (post.id === action.id) {
            return {
              ...post,
              likes: post.likes + 1
            }
          } else return post
        })
      };

проблема в том, что добавление неправильного значения к неправильному сообщению. Все посты содержат 12 лайков, когда это должно быть сообщение 1 имеет 12 лайков, а пост 2 имеет 2 лайка. В двух словах, он не отображает правильные значения для каждого элемента публикации.

{this.props.likeCount} получает пост лайков

(this.props.like) получает идентификатор сообщения.

Вот компонент Like .

import React, { Component } from 'react';
import ReactDOM from 'react-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCoffee, faAdjust } from '@fortawesome/free-solid-svg-icons';
import {connect} from 'react-redux';
import {  getLikeCount, postLike} from '../actions/';
class Like extends Component{
    constructor(props){
        super(props);
        this.state = {
            likes: null,
            heart: false
        }
    }

    clickLike = (id) => {
        this.props.postLike(id);
        // toggles between css class
        this.setState({
            heart: !this.state.heart
        })
    }
    render(){
       return(
            <div style={{float:'right', fontSize: '1.5em', color:'tomato'}} >
            <i style={{ marginRight: '140px'}} className={this.state.heart ? 'fa fa-heart':'fa fa-heart-o' }>
                    <span style={{ marginLeft: '6px'}}>
                        <a href="#" onClick={ () => this.clickLike(this.props.like)}>Like</a>       
                    </span>
                    {/* gets the like counts */}
                    {this.props.likeCount}
                </i>
            </div>       
       )
    }
}
const mapStateToProps = (state) => ({
    isEditingId: state.post.isEditingId,
    likeCount:state.post.likes
})
const mapDispatchToProps = (dispatch) => ({
    getLikeCount: (id) => dispatch(getLikeCount(id)),
    postLike: (id) => dispatch( postLike(id))
    // Pass id to the DeletePost functions.
});
export default connect(mapStateToProps, mapDispatchToProps)(Like);

Передается в компоненте PostItem, который является дочерним компонентом компонента PostList.

PostItem.js

 .....

  render(){
        const {title, id, userId, removePost, createdAt, post_content, 
        username, editForm, isEditing, editChange, myTitle, postUpdate, 
        likes,  clickLike} = this.props
        return(
            <div>
                  .....
                       <Like like={id} />
                  ........
export default connect(null, mapDispatchToProps)(PostItem);

Компонент PostList (родительский компонент)

здесь вызывается действие getLikeCount. Вызывается в функции getLikes

import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import {connect} from 'react-redux';
import {DeletePost,  getLikeCount, postLike, UpdatePost,EditChange, DisableButton} from '../actions/';
import PostItem from './PostItem';
const Styles = {
    myPaper: {
        margin: '20px 0px',
        padding: '20px'
    }
}
class PostList extends Component{
    constructor(props){
        super(props);
        this.state ={
            title: '',
        }
    }
    // Return a new function. Otherwise the DeletePost action will be dispatch each
     // time the Component rerenders.
    removePost = (id) => () => {
        this.props.DeletePost(id);
    }
    onChange = (e) => {
        e.preventDefault();
        this.setState({
            title: e.target.value
        })
    }
    formEditing = (id) => ()=> {;
        this.props.EditChange(id);
    }
    getLikes = (id) =>  {
        // console.log(id);
        this.props.getLikeCount(id)
        console.log(this.props.likeCount)
    }
    render(){
        const {posts} = this.props;
        return (
            <div>
                {posts.map((post, i) => (
                    <Paper key={post.id} style={Styles.myPaper}>
                     // getting likes here
                     {this.getLikes(post.id)}
                    {/* {...post} prevents us from writing all of the properties out */}
                        <PostItem
                             myTitle={this.state.title} 
                             editChange={this.onChange} 
                             editForm={this.formEditing} 
                             isEditing={this.props.isEditingId === post.id} 
                             removePost={this.removePost} 
                             {...post} 
                        />
                    </Paper>
                ))}
            </div>
        )
    }
}
const mapStateToProps = (state) => ({
    isEditingId: state.post.isEditingId,
})
const mapDispatchToProps = (dispatch) => ({
    // pass creds which can be called anything, but i just call it credentials but it should be called something more 
    // specific.
    EditChange: (id) => dispatch(EditChange(id)),
    UpdatePost: (creds) => dispatch(UpdatePost(creds)),
    getLikeCount: (id) => dispatch(getLikeCount(id)),
    postLike: (id) => dispatch( postLike(id)),
    // Pass id to the DeletePost functions.
    DeletePost: (id) => dispatch(DeletePost(id))
});
export default connect(mapStateToProps, mapDispatchToProps)(PostList);

1 Ответ

0 голосов
/ 23 апреля 2019

Вам следует обновить структуру данных.Вместо того, чтобы устанавливать количество лайков снаружи, оно должно быть частью поста в вашем состоянии переизбытка.Ваше действие должно включать как почтовый идентификатор, так и количество лайков.

export const getLikeCount = (id) => {
    return (dispatch, getState) => {
        return Axios.get(`/api/posts/likes/count/${id}`)
            .then( (res) => {
                 const data = res.data
                 console.log(data); // logs like counts for all posts
                 dispatch({type: GET_LIKES_COUNT, {...data, id}})
             })

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...