【问题标题】:State is empty in reducer减速器中的状态为空
【发布时间】:2017-11-27 10:30:46
【问题描述】:

我正在处理react-redux webapp,直到现在,所有操作都与ajax 请求相关,所以我使用redux thunk and axios。 现在,我正在开发一个组件,该组件将从称为“任务”的对象中创建一个列表。这应该非常简单:动作调用发送任务对象,reducer 将其添加到“任务”状态内的数组中。

问题是当调用reducer 时总是重写任务对象数组。在 reducer 调用开始时执行 console.log,我看到状态始终为空。

代码如下:

import {DROP_TASK} from '../actions/types'

export default function (state = {}, action) {
    switch (action.type){
        case(DROP_TASK):

            console.log("state", state); // here is shows object{}

            console.log('tasks', state.tasks);

            if(state.tasks === undefined || state.tasks === null ) {

                return {...state, list: [action.payload]}
            }



            return {...state, list: [...state.tasks.list, action.payload]};
        default:
            return state
    }
}

在 index.js 的 createStore

我在做:

const createStoreWithMiddleware = applyMiddleware(reduxThunk, logger)(createStore);

其中 logger 只是 console.log 每次调度前后的整个状态。所以我知道在调度 reducer 函数之前,“任务”是在第一次调用之后填充的。

这是我如何组合减速器:

import { combineReducers } from 'redux';
import {reducer as form} from 'redux-form';
import {reducer as uiReducer} from 'redux-ui';
import authReducer from './auth_reducer';
import treeReducer from './tree_reducer';
import media_asset_list_reducers from './media_asset_list_reducers';
import tasks from './tasks';

const reducers = combineReducers({
    form: form,
    auth: authReducer,
    tree: treeReducer,
    media_asset_list: media_asset_list_reducers,
    tasks: tasks,
    ui: uiReducer
});


export default reducers;

谁能帮帮我?

谢谢

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    您没有展示如何组合减速器。但在我看来,你的 reducer 有一半是为了获取表单 tasks.list 中的子状态而编写的,但它会在表单中返回新状态。

    如果您使用 combineReducers 组合 reducer,则每个组合的 reducer 只会获得其状态的子部分(这也是它应该返回的内容)

    【讨论】:

    • 抱歉,我刚刚添加了 combine reducers 部分。
    • ok 所以 if(state.tasks === undefined || state.tasks === null ) 显然是错误的,这个 reducer 作为 state 参数得到的是 allready state.tasks
    • 我投了赞成票,但是:Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score. ;-)
    【解决方案2】:

    试试:

    import {DROP_TASK} from '../actions/types'
    
    export default function (state = {}, action) {
        switch (action.type){
            case(DROP_TASK):
                return {...state, list: [...state.list, action.payload]};
            default:
                return state
        }
    }
    

    您的 reducer 将收到状态的 state.tasks 切片,因此无需在此 reducer 中包含 .tasks。

    这将产生如下状态树:

    {
      ... //other reducers
      tasks: {
        list: []
      }
    }
    

    如果您想删除 list 层并仅将 tasks 作为列表,您可以将 reducer 更改为:

    import {DROP_TASK} from '../actions/types'
    
    export default function (state = [], action) {
        switch (action.type){
            case(DROP_TASK):
                return [...state, action.payload];
            default:
                return state
        }
    }
    

    另外,DROP_TASK 似乎是一种奇怪的操作类型,用于将项目添加到 list...但不了解您的应用的更多信息,这可能仍然合适,所以如果是这样,请忽略它。

    【讨论】:

      猜你喜欢
      • 2016-04-23
      • 1970-01-01
      • 2019-04-20
      • 2021-07-18
      • 1970-01-01
      • 2017-07-03
      • 2018-08-08
      • 1970-01-01
      相关资源
      最近更新 更多