Новый документ combReducers в порядке, но он не объясняет, что вы должны называть reducer стороной государства, которым он управляет.
Это как бы говорит, если вы прочитаете это полностью, не пропуская:
Результирующий редуктор вызывает каждый дочерний редуктор и собирает их результаты в один объект состояния. Форма объекта состояния соответствует ключам переданных редукторов.
Но я согласен, что это должно быть более заметным, поскольку люди часто пропускают это предложение.
Помогут ли вам изменения с # 399?
Я бы предпочел меньше компьютерных знаний, подробное замечание об этом соглашении сразу после примера:
Обратите внимание, что редукторы называются
todos
иcounter
- точно так же, как части состояния, которые мы им передаем.Чтобы передать часть состояния редуктору, Redux использует _convention_ - редуктор должен называться точно так
Я думаю, что № 399 - это хорошо, но это объяснение для _Flux users_. Я еду в Редукс прямо с лодки. Некоторая форма моего текста была бы более полезной для случайных разработчиков JavaScript.
Важная идея здесь: Соглашения являются частью API . Не менее важно createRedux
, createDispatcher
и любые другие функции API. Всегда явно указывайте соглашения, потому что они являются частью API.
Кстати, я все еще не понимаю, как передать часть состояния редуктору. Мне к ним присоединиться camelCase или что-то в этом роде? state={owner: {name: 'John'} }
→ export function ownerName(state = [], action)
?
Спасибо за отзыв, это очень ценно.
Я хочу подчеркнуть, что
Соглашения являются частью API
не совсем правда.
Вероятно, нам следует просто избегать import *
в документации, потому что люди считают, что это неотъемлемая часть API, когда его совсем нет, и это просто удобный ярлык, который я использую.
Имена функций имеют значение только из-за того, как работают ES6 export
и import * as
.
Кстати, я все еще не понимаю, как передать часть состояния редуктору. Мне к ним присоединиться camelCase или что-то в этом роде? state = {owner: {name: 'John'}} → функция экспорта ownerName (state = [], действие)?
Нет :-). Это не волшебный API. combineReducers(object)
объединяет несколько редукторов в один и передает части состояния своим значениям с помощью предоставленных вами ключей. Он делает это ровно на один уровень в глубину. Нет никакой «магии построения целого дерева». Вам решать, как разделить редюсер на несколько функций:
// 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, будет натяжкой. Но это то, что подталкивает людей учиться и разбираться в этих вещах. Так что на самом деле это хорошо, когда чтение опережает знания и опыт читателя.
Мы меняем примеры, чтобы явно вызывать combineReducers
в reducers/index
так что, надеюсь, теперь это будет иметь больше смысла: https://github.com/gaearon/redux/pull/473
Закрытие, поскольку этот вопрос, кажется, лучше рассматривается в текущих документах.
И мы больше не используем import *
в документации.
Вы действительно думаете, что внедрение такого неявного поведения - это хорошая практика кодирования?
Для меня это запутывает код, и combReducer не должен существовать, он добавляет ненужный шаг абстракции и усложняет процесс.
Когда вы пишете фреймворк, такая важная функция, как эта, должна быть легко понятной, что, очевидно, не так, например, "волшебное" ощущение.
PS: Я исхожу из официальной документации Redux: "Это не волшебство"
Самый полезный комментарий
Спасибо за отзыв, это очень ценно.
Я хочу подчеркнуть, что
не совсем правда.
Вероятно, нам следует просто избегать
import *
в документации, потому что люди считают, что это неотъемлемая часть API, когда его совсем нет, и это просто удобный ярлык, который я использую.Имена функций имеют значение только из-за того, как работают ES6
export
иimport * as
.Нет :-). Это не волшебный API.
combineReducers(object)
объединяет несколько редукторов в один и передает части состояния своим значениям с помощью предоставленных вами ключей. Он делает это ровно на один уровень в глубину. Нет никакой «магии построения целого дерева». Вам решать, как разделить редюсер на несколько функций:Они даже не имеют значения, если вы используете помощник
combineReducers
если вы сами создаете объект :Вы можете делать это много раз.
До:
Понимаете? Это просто функции, вызывающие функции. Никаких волшебных «глубинных вещей».
И вы также можете использовать
combineReducers
много раз:Единственная часть, где имена функций имеют значение, - это когда вы используете
export
+import * as
для «получения» объекта, который вы передаетеcombineReducers
потому что _так жеimport *
работает_ ! Он помещает вещи в объект на основе их ключей экспорта.Я думаю, что моя самая большая ошибка здесь в том, что я предполагаю, что читатель знаком с именованным экспортом.