为什么从reducer返回的状态被包裹在一个对象中

时间:2018-10-18 18:15:39

标签: reactjs redux react-redux

我正在使用来自“ react-redux”的连接功能将状态和动作映射为组件中的道具。二手组合减速器如下:

import { combineReducers } from "redux";
import userDetails from "./userDetails";    
export default combineReducers({
  userDetails
});

在将调试器放入mapStateToProps函数中时 enter image description here ,状态对象不是顶级对象,而是包装在key:userDetails下,它是reducer之一的名称:

 import { FETCH_USER_DETAILS } from "../actions/type";

const reducer = (state = null, action) => {
  switch (action.type) {
    case FETCH_USER_DETAILS:
      return {
        ...{
          ...action.payload,
          isLoading: false
        }
      };
    default:
      return state;
  }
};

export default reducer;

现在由于状态对象在顶层不可用,所以我必须在mapStateToProps内部添加更多逻辑,如下所示:

const mapStateToProps = state => {
  if (state.userDetails)
    return {
      title: state.userDetails.title,
      author: state.userDetails.author,
      rating: state.userDetails.rating,
      reviews: state.userDetails.reviews,
      isLoading: state.userDetails.isLoading
    };
  else return {};
};

是否有任何方式可以使reducer返回到商店的状态不会被包装在任何对象中(对象键与reducer名称相同) 这样我就可以简化mapStateToProps函数,如下所示:

const mapStateToProps = ({ title, author, reviews, rating, isLoading }) => ({
  title,
  author,
  reviews,
  rating,
  isLoading
});

2 个答案:

答案 0 :(得分:2)

combineReducer就是这里

import { combineReducers } from "redux";
import userDetails from "./userDetails";    
export default combineReducers({
  userDetails
});

combineReducers函数通常用于组合许多不同的化简器,因此每个“化简器”都被限定在其自己的键中。在您的情况下,您需要使userDetails减速器(从文件导入)的所有工作都可以在userDetails键中使用。

如果您想要一个平坦的状态(可以肯定的是,稍后您会改变主意),则只需:

  • 按原样导出userDetails(不需要combineReducers),但是您只能使用一个reducer。
  • 使用另一个功能合并状态,命名为reduceReducers(请检查npm上的reduce-reducers包)。

答案 1 :(得分:1)

  

有什么办法可以使reducer返回到商店的状态不会被包装在任何对象{对象名与reducer名称相同”中,以便我可以如下简化mapStateToProps函数

是的,您可以删除combineReducers()

export default userDetails;

但是,对我来说,这似乎不是一个好主意,因为这意味着您必须将所有内容都保存在一个减速器中。对于简单的应用程序来说,可能还可以,但是对于更复杂的应用程序,在状态对象中具有顶级键来组织数据非常有帮助。

话虽如此,我认为您在mapStateToProps()中所做的工作很多,却收效甚微。您可以简化为:

const mapStateToProps = state => {
    if (state.userDetails) {
        return state.userDetails;
    } else {
        return {};
    }
}