combineReducers 破坏 Redux 状态并破坏多个 ImmutableJs 减速器

Posted

技术标签:

【中文标题】combineReducers 破坏 Redux 状态并破坏多个 ImmutableJs 减速器【英文标题】:combineReducers destroys Redux state and also breaks multi ImmutableJs reducers 【发布时间】:2016-07-25 00:57:09 【问题描述】:

在这件事上撞了我的头。我已经熟悉了典型的 ReactJS 和 Redux 应用程序,并且正在开发自己的应用程序。问题是当使用 combineReducers() 为 Redux 存储创建单个 reducer 时。我目前有三个减速器,当它们作为 createStore() 的减速器参数添加时,它们本身可以正常工作。第一个 reducer 保存了我所有的动作,被称为:

HeaderReducer

import  isActive  from '../actions/HeaderActions';

export const initialButtonState = 
  isActive: false,
  invertStyles: false


export default (state = initialButtonState, action) => 
  switch (action.type) 
    case 'SET_ACTIVE':
      return 
        ...state,
        isActive: action.isActive(state),
        invertStyles: action.invertStyles(state),
      

    default:
      return state
  

第二个和第三个 reducer 是使用 ImmutableJS 构建的,用于为单独的列表传播一些虚拟内容。同样,这些减速器单独工作,但在 combineReducers() 组合它们时不会。第二个reducer文件被调用:

列表项

import Immutable from 'immutable';

const messagesList = Immutable.List(['9:00AM - 9:30AM','10:30AM -     11:30AM','11:45AM - 12:30PM','1:00PM - 2:15PM','3:00PM - 4:00PM']);

export default (state = messagesList, action) => 
  switch(action.type) 
    case 'addItem':
      return state.push(action.item)
    case 'deleteItem':
      return state.filter((item, index) => index !== action.index)
    default:
      return state
  

第三个文件被调用:

行情列表

import Immutable from 'immutable';

const quotesList = Immutable.List(['Company A: 100.00$','Company B:     200.00$','Company C: 300.00$','Company D: 400.00$','Company E: 500.00$<']);

export default (state = quotesList, action) => 
  switch(action.type) 
    case 'addItem':
      return state.push(action.item)
    case 'deleteItem':
      return state.filter((item, index) => index !== action.index)
    default:
      return state
  

我在 reducers 文件夹中通过 index.js 导出了所有文件:

index.js

export  default as HeaderReducers  from './HeaderReducers';
export  default as ListItems  from './MessageList';
export  default as QuotesList  from './QuotesList';

然后调用创建我的商店:

Store.js

import  createStore, combineReducers  from 'redux';
import * as reducers from '../reducers';
// import HeaderReducers from '../reducers/HeaderReducers';
// import ListItems from '../reducers/MessageList';
// import QuotesList from '../reducers/QuotesList';

// let reducer = combineReducers( ListItems: ListItems, quotes:     QuotesList)

// export default createStore(ListItems)

const reducer = combineReducers(reducers);
export default createStore(reducer);

在启动时记录 store 的状态会返回一个 Object 或 List,这取决于我使用的 reducer。当我通过 combineReducer() 运行它们时,我得到一个返回的对象,将每个减速器保持在一起。立即中断的是我在 ListItems.js 中设置的 .map 函数

import React from 'react';
import  connect  from 'react-redux';
import NewItem from './NewItem';
import  addItem, deleteItem  from '../../../actions/HeaderActions';
    const ListItems = (ListItems, dispatch) => (
      <div>
        <ul>
          ListItems.map((ListItem, index) => <li><span key=index>    ListItem <button onClick=e => 
            dispatch(deleteItem(index))
          >X</button></span></li>)
        </ul>

        <NewItem />
      </div>
    )
function mapStateToProps(ListItems) 
  return 
    ListItems,
  

export default connect(mapStateToProps)(ListItems)

控制台显示“_ListItems.map 不是函数”。我已经完成并尝试编辑 mapStateToProps 返回值,但我抓​​住了稻草。感谢您阅读本文。任何帮助都非常感谢。

【问题讨论】:

【参考方案1】:

combine reducers 不适用于 Immutable 结构,需要通过对账来检测变化,可以使用redux-immutable:

import 
  combineReducers
 from 'redux-immutable';

import 
  createStore
 from 'redux';

const initialState = Immutable.Map();
const rootReducer = combineReducers();
const store = createStore(rootReducer, initialState);

我最近在工作中的一个项目中使用了它,但是看看你的代码,我会说同时拥有不可变和可变状态通常是一个坏主意,你应该保持它具有简单的结构或完全不可变。

尽管 ImmutableJS 很棒,但它没有直接集成到语言中(它是一个用户库)这一事实可能会导致非常冗长的代码库,另一种选择是使用 Object.freeze 来防止对您的状态和这样你就可以让普通的 combine reducer 远离 redux。

【讨论】:

【参考方案2】:

combineReducers 不支持不可变。改用redux-immutablecombinReducers。

【讨论】:

我的两个减速器是不可变的。一个不是。如何组合所有 reducer,无论是否不可变? 我自己从未尝试过,我对此很确定,但我认为您必须将减速器转换为不可变的。

以上是关于combineReducers 破坏 Redux 状态并破坏多个 ImmutableJs 减速器的主要内容,如果未能解决你的问题,请参考以下文章

Redux - 理解 combineReducers

Redux 中的CombineReducer的函数详解

Redux 中 combineReducers实现原理

关于redux和react-redux使用combinereducers之后的问题

4 react 简书 引入 redux 的 combineReducers 对 redux 数据进行管理

使用打字稿反应 redux combinereducer 时出错