【问题标题】:Is this reducer compliant with the Redux rules?这个 reducer 是否符合 Redux 规则?
【发布时间】:2017-12-10 18:53:06
【问题描述】:

我很困惑,因为我这里不返回状态,只返回action.payload(代码sn-p):

case HISTORY_SELECTED:
  return action.payload;

所有reducer代码:

import { HISTORY_SELECTED } from '../actions/index';

export default function (state = null, action) {
  switch (action.type) {
    case HISTORY_SELECTED:
      return action.payload;
    default:
      return state;
  }
}

编辑:增加了 3 个案例。

如果我以正确的方式理解答案,CASE 2、CASE 3 和 CASE 4 也可以,是吗?

案例 2 (reducer_note_selected.js)

import { NOTE_SELECTED, DEL_NOTE_SUCCESS } from '../actions/actions';

export default function (state = null, action) {
  switch (action.type) {
    case NOTE_SELECTED:
      return action.payload;
    case DEL_NOTE_SUCCESS:
      return null;
    default:
      return state;
  }
}

案例 3(reducer_notes_status_fetch.js - 这里我只返回字符串)

 import {
 FETCH_ALL_NOTES_STARTED,
 FETCH_ALL_NOTES_ERROR,
 FETCH_ALL_NOTES_SUCCESS 
} from '../actions/actions';

    export default function (state = {}, action) {
      switch (action.type) {
        case FETCH_ALL_NOTES_STARTED:
          return 'fetching_started';
        case FETCH_ALL_NOTES_ERROR:
          return 'error';
        case FETCH_ALL_NOTES_SUCCESS:
          return 'fetch_all_notes_success';
        default:
          return state;
      }
    }

案例 4 (reducer_notes_general.js)

import _ from 'lodash';
import { FETCH_ALL_NOTES_SUCCESS, DEL_NOTE_SUCCESS } from '../actions/actions';

export default function (state = {}, action) {
  switch (action.type) {
    case FETCH_ALL_NOTES_SUCCESS:
      return _.mapKeys(action.payload.data, '_id');
    case DEL_NOTE_SUCCESS:
      return _.omit(state, action.payload);
    default:
      return state;
  }
}

【问题讨论】:

  • 是的,但是“下一个状态”可以只是来自操作的数据。
  • 我可以像以前那样做吗?还是违反规则?我很困惑我到底能在减速器中返回什么。
  • 是的,你可以,根据我的回答。 reducer 返回的“新状态”可能基于旧状态、基于操作的数据,甚至是您从头开始计算的数据。

标签: javascript reactjs redux react-redux


【解决方案1】:

是的,从概念上讲,reducer 绝对没问题。这仅仅意味着您想用action.payload 的内容替换现有状态。这里有一个类似的例子来说明原理:

function todosReducer(todos = [], action) {
    switch(action.type) {
        case LOAD_TODOS: {
            return action.payload.loadedTodos;            
        }
        default: return state;
    }
}

因此,在这种情况下,reducer 返回的“新状态”来自操作的数据,而不是基于旧状态计算的数据。

唯一需要注意的是,如果您的动作创建者从 Redux 状态中获取了一个现有值并将其包含在动作中,那么您最终可能实际上并没有更改任何内容。我在a recent SO question about a reducer "updating while just returning state" 中帮助调试了类似的问题。

【讨论】:

  • 非常感谢您的回答!所以我可以做这样的事情吗?这也可以,对吗? 将此代码移至主要问题
【解决方案2】:

我不同意@hindmost,你正在用你的有效载荷值替换状态。这就是 react-redux 链的工作方式。希望这将为您解决问题。

  • 反应 - 有人点击了一个按钮(任何事件),我会把它发送给 行动。
  • 行动 - 明白了。我将调度操作,以便减速器可以 更新状态
  • Reducer - 我得到了当前状态和新动作。我会做一个新的 复制状态并传递它

  • Store - 我看到 reducer 更新了状态。我会确保所有 连接的组件都知道变化

  • React-Redux - 获得新数据。生病确定我是否应该更新 对这些变化做出反应。我不想费心更新 UI 如果没有必要。

  • React - 从商店获取我的道具中的新数据。生病更新 反映更改的 UI。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多