反应 redux 不可变状态

react redux immutable state

我创建了一个喜欢按钮和一个不喜欢按钮。默认情况下,我的图片有不喜欢按钮。当我点击不喜欢按钮时,我希望这个按钮消失,而喜欢按钮取而代之。我的问题是状态在我检查时发生了变化,但我在页面上看不到变化,除非我重新加载页面:变化保存在数据库中。有谁知道如何解决这个问题? 这是我的减速器。

我的初始状态:

const initialState = {
    loading: false,
    stories: [],
    error: "",
    currentPage: 1,
    totalPages: null,
    totalStories: null
}

 case LIKE:
        return {
            ...state,
            stories: state.stories.map(storie => {
                if(storie.id === action.payload.id) {
                    return  { ...storie, 
                        userlikes: action.payload.userlikes
                    }

                } else {
                    return storie;
                }
            })
        }

这是我所有的reducer

import {FETCH_GALLERY_REQUEST, FETCH_GALLERY_SUCCESS, FETCH_GALLERY_FAILURE, GALLERY_CLEAR, LIKE, DISLIKE } from "./galleryTypes";

const initialState = {
    loading: false,
    stories: [],
    error: "",
    currentPage: 1,
    totalPages: null,
    totalStories: null
}

const galleryReducer = (state = initialState, action) => {
    switch(action.type) {
        case FETCH_GALLERY_REQUEST:
            return {
                ...state,
                loading: action.payload,
            }
            
        case GALLERY_CLEAR:
            return {
                ...state,
                loading: false,
                stories: [],
                error: "",
                currentPage: 1,
                totalPages: null,
                totalStories: null
        }
        
        case FETCH_GALLERY_SUCCESS:
            return {
                ...state,
                loading: false,
                stories: [...state.stories, ...action.payload].filter( 
                    (storie, index) => index === [...state.stories, ...action.payload].findIndex( 
                        elem => elem.id === storie.id && elem.id === storie.id
                        )
                    ),
                currentPage: action.currentPage,
                totalPages: action.totalPages,
                totalStories: action.totalStories,
                error: ""
            }
    
        case FETCH_GALLERY_FAILURE:
            return {
                ...state,
                loading: false,
                stories: [],
                error: action.payload
            }

        
        case LIKE:
            return {
                ...state,
                stories: state.stories.map(storie => {
                    if(storie.id === action.payload.id) {
                        return  { 
                            ...storie, 
                            userlikes: action.payload.userlikes
                        }

                    } else {
                        return storie;
                    }
                })
            }


        default: 
            return state;
    }
}

export default galleryReducer

这是我的 vue 组件

 // permet d'ajouter un like
addLike = (story_id, user_id, index) => {
    const data = {
        story_id: story_id,
        user_id: user_id
    }
    this.props.like(story_id);
    this.props.fetchLike(data);

}

// permet denlever un like
removeLike = (story_id, user_id) => {
    this.setState({
        story_id: story_id
    })

    const data = {
        story_id: story_id,
        user_id: user_id
    }

    this.props.disLike(story_id);
    this.props.fetchDislike(story_id, user_id);
    
}

我的渲染

{storiesData.stories.map((storie, index) => (
  <div
    key={index}
    className="everyprofile-container_details item"
    style={{ height: "450px" }}
  >
    <div className="everyprofile_name">
      <span className="everyProfile-firstname"> {storie.firstname} </span>
      <span className="everyProfile-lastname"> {storie.lastname} </span>
    </div>
    <div className="everyprofile-photo_cadre">
      <div
        className="everyprofile-photo"
        style={{
          backgroundImage: `url(${config.API_URL}resources/pictures_min/${storie.picture_path})`,
          backgroundPositionY: `${storie.bg_position_y}%`,
          backgroundPositionX: `${storie.bg_position_x}%`,
          backgroundSize: "cover"
        }}
      >
        {storie.userlikes == 1 ? (
          <button
            onClick={() => this.removeLike(storie.id, user_id, index)}
            className="everyprofile-like-btn"
            style={{ color: "#FF0000" }}
          >
            <Icon size={40} icon={ic_favorite} />
          </button>
        ) : (
          <button
            onClick={() => this.addLike(storie.id, user_id, index)}
            className="everyprofile-like-btn"
            style={{ color: "#FF0000" }}
          >
            <Icon size={40} icon={ic_favorite_border} />
          </button>
        )}
      </div>
    </div>
    <div className="everyprofile-container-story">
      <div className="everyprofile-story">{storie.story}</div>
    </div>
  </div>
))}


const mapStateToProps = (state) => {
  return {
    storiesData: state.stories,
    loading: state.stories.loading,
    currentPage: state.stories.currentPage,
    totalPages: state.stories.totalPages,
    totalStories: state.stories.totalStories,
    validateStory: state.validateStorie.validateStory,
    searchStatus: state.searchStatus.searchBar,
    query: state.query.query
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    // fetchEveryProfile: (storyId, userId) => dispatch(fetchEveryProfile(storyId, userId)),
    fetchLike: (data) => dispatch(fetchLike(data)),
    fetchDislike: (story_id, user_id) => dispatch(fetchDislike(story_id, user_id)),
    like: (story_id) => dispatch(like(story_id)),
    disLike: (story_id) => dispatch(disLike(story_id)),


    fetchGalleryFirst: (searchInfo) => dispatch(fetchGalleryFirst(searchInfo)),
    fetchGallery: (searchInfo) => dispatch(fetchGallery(searchInfo))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(EvryProfile)

这是动作

// Permet d'enlever le bouton like
export const like = (story_id) => {
    return {
        type: LIKE,
        payload: {
            id: story_id,
            userlikes: 1
        }
    }

}

// Permet d'enlever le bouton dislike
export const disLike = (id) => {
    return {
        type: DISLIKE,
        payload: id
    }
}

问题

您的减速器似乎缺少案例处理 DISLIKE。根据您的 LIKE 案例和 UI 逻辑,我假设将 stories[someIndex].userlikes 更新为 1 以外的任何值应该将不喜欢按钮切换回喜欢按钮。

追踪步骤

  1. 单击按钮并调用 removeLike
  2. removeLike 调度 disLikefetchDislike 动作
  3. 我假设 fetchDislike 是一个异步操作,即 thunk、epic、saga 等...并且有效,但是 dislike 应该在 reducer 中处理。
  4. 查看 reducer,看不到 case 处理 DISLIKE

解决方案

添加案例以处理 DISLIKE 并更新特定故事的 userlikes 属性.

switch (true) {
  case DISLIKE:
    return {
      ...state,
      stories: state.stories.map((story) =>
        storie.id === action.payload.id
          ? {
              ...story,
              userlikes: 0
            }
          : story
      )
    };
}