【问题标题】:How to correctly update my initialState in react-redux如何在 react-redux 中正确更新我的 initialState
【发布时间】:2017-06-05 03:13:11
【问题描述】:

我有一个初始状态:

export default {
  dashboards: [],
  dashboardContent: []
};

我想在这样的动作调度之后通过减速器更新:

import initialState from './initialState';
import * as types from '../actions/actionTypes';

export default function dashboardContentReducer(state = initialState, action) {
  switch(action.type) {
    case types.LOAD_DASHBOARD_CONTENT_SUCCESS:
      return Object.assign({}, state, { dashboardContent: action.dashboardContent });
    default:
      return state;
  }
}

import initialState from './initialState';
import * as types from '../actions/actionTypes';

export default function dashboardReducer(state = initialState, action) {
  switch(action.type) {
    case types.LOAD_DASHBOARDS_SUCCESS:
      return Object.assign({}, state, { dashboards: action.dashboards });
    default:
      return state;
  }
}

调度操作后,当我查看我的商店时,我看到它已更新,但太深了一层:

{
  dashboards: {
    dashboards: [/* array received from reducer */],
    dashboardContent: []
  },
  dashboardContent: {
    dashboards: [],
    dashboardContent: [/* array received from reducer */]
  }
}

我怎样才能让它变成我想要的,这应该是:

{
  dashboards: [/* payload received from reducer */],
  dashboardContent: [/* payload received from reducer */]
}

编辑:

这是有效载荷的外观。

对于仪表板内容:

[
  {
    application: 'Company News',
    site: 'Home',
    lastUpdated: 'Jun 1, 2016 10:30',
    location: 'Asbury',
    views: 123451,
    individuals: 2345
  },
  {
    application: 'Company News',
    site: 'Home',
    lastUpdated: 'Jun 1, 2016 10:30',
    location: 'Asbury',
    views: 123451,
    individuals: 2345
  },
  {
    application: 'Company News',
    site: 'Home',
    lastUpdated: 'Jun 1, 2016 10:30',
    location: 'Asbury',
    views: 123451,
    individuals: 2345
  },
  {
    application: 'Company News',
    site: 'Home',
    lastUpdated: 'Jun 1, 2016 10:30',
    location: 'Asbury',
    views: 123451,
    individuals: 2345
  },
  {
    application: 'Company News',
    site: 'Home',
    lastUpdated: 'Jun 1, 2016 10:30',
    location: 'Asbury',
    views: 123451,
    individuals: 2345
  }
];

对于仪表板:

[
  {
    id: 1,
    title: "Overview",
    template: "main",
    category: "Main",
    sort: {},
    filter: {
    loginType: "All Accounts",
    Pivot: "location",
    pivotValue: 1
    },
    priority: 0,
    readonly: true
  },
  {
    id: 2,
    title: "Top Applications",
    template: "application-usage",
    category: "Application Usage",
    sort: {
      first: {
        by: "views",
        direction: "desc"
      },
      second:  {
        By:"individuals",
        direction: "desc"
      }
    },
    filter: {
      application: 0,
      Pivot: location,
      pivotValue: 1
    },
    priority: 1,
    readonly: true,
    createdDate: "2016-12-29T16:37:11.62Z",
    updatedDate: "2016-12-29T16:37:11.62Z"
  }
]

【问题讨论】:

  • 可能action payload不是一个数组,而是一个与初始状态具有相同形状的对象。
  • 事实并非如此。我将更新帖子以包含有效负载的外观。
  • 试试这个代码,如果它有效:return Object.assign({}, state, action.dashboards);
  • 很遗憾没有...
  • 你在使用combineReducers吗?因为这将创建两个不同的状态对象

标签: javascript reactjs ecmascript-6 redux react-redux


【解决方案1】:

既然您使用了两个不同的减速器,并且您知道 initialState ,为什么不将您的减速器修改为

import initialState from './initialState';
import * as types from '../actions/actionTypes';

export default function dashboardContent(state = [], action) {
  switch(action.type) {
    case types.LOAD_DASHBOARD_CONTENT_SUCCESS:
      return Object.assign({}, state, action.data);
    default:
      return state;
  }
}

另一个是

import initialState from './initialState';
import * as types from '../actions/actionTypes';

export default function dashboard(state = [], action) {
  switch(action.type) {
    case types.LOAD_DASHBOARDS_SUCCESS:
      return Object.assign({}, state, action.data);
    default:
      return state;
  }
}

好吧,我已经更改了减速器的名称,但是在使用combineReducers 时,无论如何命名并不重要。你可以一直这样做。

combineReducers({
  dashboardContent:dashboardContentReducersWhichHasBeenGivenAWeirdName,
  dashboard:dashboardReducerAgainNamedWeird
})

您的状态将被创建为{dashboard:[],dashboardContent:[]}

通过这种方式,您可以避免错误级别的更新。 我还建议看一下 explanation here by Dan ,它详细解释了 createStore 如何根据您的减速器创建状态,以及 intialState 如何优先。

【讨论】:

  • 为什么state = [] 在第一个,state = initialState 在第二个?
  • 另外,你是什么意思 combineReducers 命名无关紧要?这意味着什么?
  • @iggy2012 对不起,这是一个错字,扩大了答案。 !
【解决方案2】:

来自combineReducers 文档:

生成的 reducer 调用每个子 reducer,并收集他们的 结果为单个状态对象。状态对象的形状 匹配传递的 reducer 的键。

因此,状态对象将如下所示:

{
  reducer1: ...
  reducer2: ...
}

所以在使用的时候,为了让两个reducer共享状态,你需要像这样创建一个reducer:

import initialState from './initialState';
import * as types from '../actions/actionTypes';

export default function dashboardReducer(state = initialState, action) {
  switch(action.type) {
    case types.LOAD_DASHBOARDS_SUCCESS:
      return Object.assign({}, state, { dashboards: action.dashboards });
    case types.LOAD_DASHBOARD_CONTENT_SUCCESS:
      return Object.assign({}, state, { dashboardContent: action.dashboardContent });
    default:
      return state;
  }
}

或者,如果您出于某种原因想要保持逻辑分离,您可以使用reduce-reducers 库:

import reduceReducers from "reduce-reducers";
import dashboardReducer from "./dashboardReducer";
import dashboardContentReducer from "./dashboardContentReducer";

const combined = reduceReducers(dashboardReducer, dashboardContentReducer);

createStore(combineReducers({ dashboard: combined }));

这样你就会有一个状态对象:

{
    dashboard: {
        dashboards: []
        dashboardContent: []
    }
}

【讨论】:

    【解决方案3】:

    您需要针对内部dashboards 而不是外部的。试试

    export default function dashboardReducer(state = initialState, action) {
      switch(action.type) {
        case types.LOAD_DASHBOARDS_SUCCESS:
          return Object.assign({}, state, { 
                    dashboards: Object.assign({},state.dashboards,{dashboards: action.dashboards}
                 });
        default:
          return state;
      }
    }
    

    export default function dashboardContentReducer(state = initialState, action) {
      switch(action.type) {
        case types.LOAD_DASHBOARD_CONTENT_SUCCESS:
          return Object.assign({}, state, { 
                    dashboards: Object.assign({},state.dashboards,{dashboardContent: action.dashboardContent}
                 });
        default:
          return state;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 2016-12-14
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2021-12-06
      • 2020-01-28
      相关资源
      最近更新 更多