Redux: Das `combineReducers`-Dokument erklärt nicht, wie man erkennt, welcher Teil des Zustands an den Reducer übergeben werden soll

Erstellt am 8. Aug. 2015  ·  7Kommentare  ·  Quelle: reduxjs/redux

docs

Hilfreichster Kommentar

Danke für das Feedback, es ist sehr wertvoll.

das möchte ich betonen

Konventionen sind Teil der API

stimmt nicht wirklich.

Wir sollten import * in den Dokumenten wahrscheinlich einfach vermeiden, weil die Leute davon ausgehen, dass es ein integraler Bestandteil der API ist, obwohl dies überhaupt nicht der Fall ist, und es ist nur eine bequeme Verknüpfung, die ich verwende.

Funktionsnamen sind nur aufgrund der Funktionsweise von ES6 export und import * as .

Übrigens, ich bin immer noch verwirrt, wie man einen Teil des Zustands an den Reduzierer weitergibt. Soll ich camelCase mitmachen oder so? state={owner: {name: 'John'} } → Exportfunktion ownerName(state = [], action)?

Nein :-). Es ist keine magische API. combineReducers(object) kombiniert mehrere Reduzierer zu einem und übergibt Teile des Zustands durch die von Ihnen bereitgestellten Schlüssel an seine Werte. Es tut dies nur genau eine Ebene tief. Es gibt keine „Baumzauberei“. Es liegt an Ihnen, einen Reduzierer in mehrere Funktionen aufzuteilen:

// 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);

Sie spielen nicht einmal eine Rolle, wenn Sie den combineReducers Helfer verwenden , solange Sie das Objekt selbst erstellen :

// 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);

Sie können dies viele Male tun.

Vor:

// 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);

Siehst du? Es sind nur Funktionen, die Funktionen aufrufen. Keine magischen "Tiefensachen".
Und Sie können combineReducers viele Male verwenden:

// 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);

Der einzige Teil, bei dem Funktionsnamen von Bedeutung sind, ist, wenn Sie export + import * as , um ein Objekt zu „erhalten“, das Sie an combineReducers weil _so funktioniert import * _ ! Es fügt Dinge basierend auf ihren Exportschlüsseln in ein Objekt ein.

Ich denke, mein größter Fehler besteht darin, anzunehmen, dass der Leser mit benannten Exporten vertraut ist.

Alle 7 Kommentare

Es sagt es irgendwie, wenn Sie es vollständig lesen, ohne zu überspringen:

Der resultierende Reduzierer ruft jeden untergeordneten Reduzierer auf und sammelt deren Ergebnisse in einem einzelnen Zustandsobjekt. Die Form des Zustandsobjekts entspricht den Schlüsseln der übergebenen Reduzierer.

Aber ich stimme zu, dass dies deutlicher hervorgehoben werden muss, da die Leute diesen Satz oft übersehen.
Würden Ihnen Änderungen von #399 helfen?

Ich würde weniger Informatik bevorzugen, expliziter Hinweis zu dieser Konvention direkt nach dem Beispiel:

Beachten Sie, dass Reduzierer todos und counter heißen – genau wie die Teile des Zustands, die wir an sie übergeben.

Um einen Teil des Zustands an Reducer zu übergeben, verwendet Redux _convention_ -- Reducer sollte genau als Teil des Zustands benannt werden, den Sie an ihn übergeben möchten.

Ich denke, #399 ist gut, aber es ist eine Erklärung für _Flux-Benutzer_. Ich komme frisch vom Boot nach Redux. Eine Form meines Textes wäre für Gelegenheits-JavaScript-Entwickler hilfreicher.

Wichtiger Gedanke dabei ist: Konventionen sind Teil der API . Es ist genauso wichtig wie createRedux , createDispatcher und jede andere API-Funktion. Geben Sie Konventionen immer explizit an, da sie Teil der API sind.

Übrigens, ich bin immer noch verwirrt, wie man einen Teil des Zustands an den Reduzierer weitergibt. Soll ich camelCase mitmachen oder so? state={owner: {name: 'John'} }export function ownerName(state = [], action) ?

Danke für das Feedback, es ist sehr wertvoll.

das möchte ich betonen

Konventionen sind Teil der API

stimmt nicht wirklich.

Wir sollten import * in den Dokumenten wahrscheinlich einfach vermeiden, weil die Leute davon ausgehen, dass es ein integraler Bestandteil der API ist, obwohl dies überhaupt nicht der Fall ist, und es ist nur eine bequeme Verknüpfung, die ich verwende.

Funktionsnamen sind nur aufgrund der Funktionsweise von ES6 export und import * as .

Übrigens, ich bin immer noch verwirrt, wie man einen Teil des Zustands an den Reduzierer weitergibt. Soll ich camelCase mitmachen oder so? state={owner: {name: 'John'} } → Exportfunktion ownerName(state = [], action)?

Nein :-). Es ist keine magische API. combineReducers(object) kombiniert mehrere Reduzierer zu einem und übergibt Teile des Zustands durch die von Ihnen bereitgestellten Schlüssel an seine Werte. Es tut dies nur genau eine Ebene tief. Es gibt keine „Baumzauberei“. Es liegt an Ihnen, einen Reduzierer in mehrere Funktionen aufzuteilen:

// 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);

Sie spielen nicht einmal eine Rolle, wenn Sie den combineReducers Helfer verwenden , solange Sie das Objekt selbst erstellen :

// 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);

Sie können dies viele Male tun.

Vor:

// 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);

Siehst du? Es sind nur Funktionen, die Funktionen aufrufen. Keine magischen "Tiefensachen".
Und Sie können combineReducers viele Male verwenden:

// 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);

Der einzige Teil, bei dem Funktionsnamen von Bedeutung sind, ist, wenn Sie export + import * as , um ein Objekt zu „erhalten“, das Sie an combineReducers weil _so funktioniert import * _ ! Es fügt Dinge basierend auf ihren Exportschlüsseln in ein Objekt ein.

Ich denke, mein größter Fehler besteht darin, anzunehmen, dass der Leser mit benannten Exporten vertraut ist.

Ich denke, mein größter Fehler besteht darin, anzunehmen, dass der Leser mit benannten Exporten vertraut ist.

Ich denke, die Annahme, dass der Leser mit ES6 überhaupt vertraut ist, ist eine Herausforderung. Aber das ist es, was die Leute dazu bringt, zu lernen und diese Dinge herauszufinden. Es ist also eigentlich gut, wenn das Lesen dem Wissen und der Erfahrung des Lesers voraus ist.

Wir ändern die Beispiele, um combineReducers explizit in reducers/index aufzurufen, also macht es hoffentlich von nun an mehr Sinn: https://github.com/gaearon/redux/pull/473

Schließen, da dies in den aktuellen Dokumenten besser behandelt zu werden scheint.
Und wir verwenden import * nicht mehr in Dokumenten.

Glauben Sie wirklich, dass das Einbetten eines solchen impliziten Verhaltens eine gute Programmierpraxis ist?

Für mich verschleiert es den Code und combineReducer sollte nicht existieren, es fügt einen unnötigen Abstraktionsschritt hinzu und verkompliziert den Prozess.

Wenn Sie ein Framework schreiben, sollte ein wichtiges Merkmal wie dieses leicht verständlich sein, das ist offensichtlich nicht der Fall, zB das "magische" Gefühl.

PS: Ich komme aus der offiziellen Redux-Dokumentation: "Es ist keine Magie"

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen