Redux: `combineReducers` 文档没有解释如何猜测状态的哪一部分传递给减速器

创建于 2015-08-08  ·  7评论  ·  资料来源: reduxjs/redux

新的combineReducers文档是可以的,但它没有解释您必须将 reducer 命名为它管理的状态的一方。

最有用的评论

感谢反馈,非常有价值。

我想强调的是

约定是 API 的一部分

不是真的。

我们可能应该避免在文档中使用import * ,因为人们认为它是 API 不可或缺的一部分,而它根本不是,而这只是我使用的一个方便的快捷方式。

函数名称仅取决于 ES6 exportimport * as工作方式。

顺便说一句,我仍然对如何将状态的子部分传递给减速器感到困惑。 我应该camelCase加入他们还是什么? state={owner: {name: 'John'} } → 导出函数 ownerName(state = [], action)?

不 :-)。 这不是一个神奇的 API。 combineReducers(object)将多个reducer 合二为一,并通过您提供的键将部分状态传递给其值。 它只做这完全一层深。 没有“构建整棵树魔法”。 您可以将减速器拆分为更多功能:

// Function names don't matter!
function processA(state, action) { ... }
function doSomethingWithB(state, action) { ... }

function reducer(state = {}, action) {
  return {
    // Because you call them!
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}

// Not using combineReducers
let store = createStore(reducer);

只要您自己创建对象,即使您使用combineReducers助手也无关紧要:

// Function names don't matter!
function processA(state, action) { ... }
function doSomethingWithB(state, action) { ... }

/*
function reducer(state = {}, action) {
  return {
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}
*/
let reducer = combineReducers({
  a: processA,
  b: doSomethingWithB
});

let store = createStore(reducer);

你可以多次这样做。

前:

// Function names don't matter!
function processSomePartOfA(state, action) { ... }
function doSomethingWithOtherPartOfA(state, action) { ... }

function processA(state, action) {
  return {
    // Because you call them!
    somePart: processSomePartOfA(state.somePart),
    otherPart: doSomethingWithOtherPartOfA(state.otherPart)
  }
}
function doSomethingWithB(state, action) { ... }

function reducer(state = {}, action) {
  return {
    // Because you call them!
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}

// Not using the helper
let store = createStore(reducer);

你看? 这只是函数调用函数。 没有神奇的“深层次的东西”。
你也可以多次使用combineReducers

// Function names don't matter!
function processSomePartOfA(state, action) { ... }
function doSomethingWithOtherPartOfA(state, action) { ... }

/*
function processA(state, action) {
  return {
    somePart: processSomePartOfA(state.somePart),
    otherPart: doSomethingWithOtherPartOfA(state.otherPart)
  }
}
*/
let processA = combineReducers({
  somePart: processSomePartOfA,
  otherPart: doSomethingWithOtherPartOfA
});

function processA(state, action) { ... }
function doSomethingWithB(state, action) { ... }

/*
function reducer(state = {}, action) {
  return {
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}
*/
let reducer = combineReducers({
  a: processA,
  b: doSomethingWithB
});

let store = createStore(reducer);

函数名称唯一重要的部分是当您使用export + import * as来“获取”传递给combineReducers因为_这就是import * _ ! 它根据导出键将事物放入对象中。

我认为我最大的错误是假设读者熟悉命名导出。

所有7条评论

如果你完整地阅读它,没有跳过,它有点说:

生成的减速器调用每个子减速器,并将它们的结果收集到单个状态对象中。 状态对象的形状与传递的减速器的键相匹配。

但我同意这需要更加突出,因为人们经常错过这句话。
#399 的改动对你有帮助吗?

我更喜欢较少的计算机科学,在示例之后立即明确说明此约定

请注意,reducer 被命名为todoscounter —— 与我们传递给它们的状态部分完全一样。

要将部分状态传递给 reducer Redux 使用了 _convention_ ——reducer 应该准确

我认为 #399 很好,但它是对 _Flux 用户的解释。 我刚上船就来到 Redux。 我的某种形式的文本对临时的 JavaScript 开发人员更有帮助。

这里的重要思想是:约定是 API 的一部分。 它与createReduxcreateDispatcher和任何其他 API 函数同样重要。 始终明确声明约定,因为它们是 API 的一部分。

顺便说一句,我仍然对如何将状态的子部分传递给减速器感到困惑。 我应该camelCase加入他们还是什么? state={owner: {name: 'John'} }export function ownerName(state = [], action) ?

感谢反馈,非常有价值。

我想强调的是

约定是 API 的一部分

不是真的。

我们可能应该避免在文档中使用import * ,因为人们认为它是 API 不可或缺的一部分,而它根本不是,而这只是我使用的一个方便的快捷方式。

函数名称仅取决于 ES6 exportimport * as工作方式。

顺便说一句,我仍然对如何将状态的子部分传递给减速器感到困惑。 我应该camelCase加入他们还是什么? state={owner: {name: 'John'} } → 导出函数 ownerName(state = [], action)?

不 :-)。 这不是一个神奇的 API。 combineReducers(object)将多个reducer 合二为一,并通过您提供的键将部分状态传递给其值。 它只做这完全一层深。 没有“构建整棵树魔法”。 您可以将减速器拆分为更多功能:

// Function names don't matter!
function processA(state, action) { ... }
function doSomethingWithB(state, action) { ... }

function reducer(state = {}, action) {
  return {
    // Because you call them!
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}

// Not using combineReducers
let store = createStore(reducer);

只要您自己创建对象,即使您使用combineReducers助手也无关紧要:

// Function names don't matter!
function processA(state, action) { ... }
function doSomethingWithB(state, action) { ... }

/*
function reducer(state = {}, action) {
  return {
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}
*/
let reducer = combineReducers({
  a: processA,
  b: doSomethingWithB
});

let store = createStore(reducer);

你可以多次这样做。

前:

// Function names don't matter!
function processSomePartOfA(state, action) { ... }
function doSomethingWithOtherPartOfA(state, action) { ... }

function processA(state, action) {
  return {
    // Because you call them!
    somePart: processSomePartOfA(state.somePart),
    otherPart: doSomethingWithOtherPartOfA(state.otherPart)
  }
}
function doSomethingWithB(state, action) { ... }

function reducer(state = {}, action) {
  return {
    // Because you call them!
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}

// Not using the helper
let store = createStore(reducer);

你看? 这只是函数调用函数。 没有神奇的“深层次的东西”。
你也可以多次使用combineReducers

// Function names don't matter!
function processSomePartOfA(state, action) { ... }
function doSomethingWithOtherPartOfA(state, action) { ... }

/*
function processA(state, action) {
  return {
    somePart: processSomePartOfA(state.somePart),
    otherPart: doSomethingWithOtherPartOfA(state.otherPart)
  }
}
*/
let processA = combineReducers({
  somePart: processSomePartOfA,
  otherPart: doSomethingWithOtherPartOfA
});

function processA(state, action) { ... }
function doSomethingWithB(state, action) { ... }

/*
function reducer(state = {}, action) {
  return {
    a: processA(state.a, action),
    b: doSomethingWithB(state.b, action)
  };
}
*/
let reducer = combineReducers({
  a: processA,
  b: doSomethingWithB
});

let store = createStore(reducer);

函数名称唯一重要的部分是当您使用export + import * as来“获取”传递给combineReducers因为_这就是import * _ ! 它根据导出键将事物放入对象中。

我认为我最大的错误是假设读者熟悉命名导出。

我认为我最大的错误是假设读者熟悉命名导出。

我认为,假设读者完全熟悉 ES6 是一种延伸。 但这就是推动人们学习和弄清楚这些东西的原因。 因此,当阅读领先于读者的知识和经验时,这实际上是一件好事。

我们正在更改示例以在reducers/index显式调用combineReducers reducers/index所以希望从现在开始它会更有意义: https :

结束,因为这似乎在当前文档中得到了更好的解决。
我们也不再在文档中使用import *

你真的认为嵌入这样的隐式行为是一种很好的编码习惯吗?

对我来说,它混淆了代码,并且 combineReducer 不应该存在,它增加了一个不必要的抽象步骤并使过程复杂化。

当你写一个框架时,像这样的一个重要特性应该很容易理解,但显然不是这样,例如“神奇”的感觉。

PS:我来自官方 Redux 文档:“这不是魔法”

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

vraa picture vraa  ·  3评论

timdorr picture timdorr  ·  3评论

rui-ktei picture rui-ktei  ·  3评论

CellOcean picture CellOcean  ·  3评论

elado picture elado  ·  3评论