2016-10-11 3 views
0

Я пытаюсь понять официальный пример редуктора Redux.Официальный пример сокращения редуктора не ясен

Я не уверен, кто называет эту функцию «сообщений», почему она определена отдельно и почему эта функция никогда не подвергалась методу CombineReducer, но каким-то образом вызывается при отправке действий.

import { combineReducers } from 'redux' 
import { 
    SELECT_SUBREDDIT, INVALIDATE_SUBREDDIT, 
    REQUEST_POSTS, RECEIVE_POSTS 
} from './actions' 

function selectedSubreddit(state = 'reactjs', action) { 
    switch (action.type) { 
    case SELECT_SUBREDDIT: 
    return action.subreddit 
    default: 
    return state 
    } 
} 

function posts(state = { 
    isFetching: false, 
    didInvalidate: false, 
    items: [] 
    }, action) { 

    switch (action.type) { 
    case INVALIDATE_SUBREDDIT: 
     return Object.assign({}, state, { 
     didInvalidate: true 
     }) 
    case REQUEST_POSTS: 
     return Object.assign({}, state, { 
     isFetching: true, 
     didInvalidate: false 
    }) 
    case RECEIVE_POSTS: 
     return Object.assign({}, state, { 
     isFetching: false, 
     didInvalidate: false, 
     items: action.posts, 
     lastUpdated: action.receivedAt 
     }) 
    default: 
    return state 
    } 
    } 

    function postsBySubreddit(state = { }, action) { 
    switch (action.type) { 
    case INVALIDATE_SUBREDDIT: 
    case RECEIVE_POSTS: 
    case REQUEST_POSTS: 
     return Object.assign({}, state, { 
     [action.subreddit]: posts(state[action.subreddit], action) 
    }) 
    default: 
     return state 
    } 
} 

const rootReducer = combineReducers({ 
    postsBySubreddit, 
    selectedSubreddit 
}) 

export default rootReducer 

Я знаю, что она вызывается один раз по телефону postsBySubreddit (REQUEST_POSTS), но и позже, в процессе он вызывается, когда действие RECEIVE_POSTS отправляется.

Мне кажется, что у нас есть несколько слушателей в этом случае для тех же действий. Попытка понять, почему.

ответ

0

posts функция вызывается внутри функции postsBySubreddit():

case REQUEST_POSTS: 
    return Object.assign({}, state, { 
    [action.subreddit]: posts(state[action.subreddit], action) 
}) 

Это определяется отдельно, чтобы понять, как работает логика. postsBySubreddit отвечает за выяснение , который данные субредадата должны быть обновлены, а post отвечает за обновление данных для одного субредда. Это эффективно разделение проблем. Обе функции знают, как обновлять некоторые данные в ответ на данное действие.

Цитирование из документации:

По своей сути, Redux действительно довольно простой шаблон дизайна: все ваши «писать» логика идет в одну функцию, и единственный способ запустить эту логику, чтобы дать Redux простой объект, который описывает что-то, что произошло. Хранилище Redux вызывает эту функцию записи и передает в текущем дереве состояний и описательном объекте логическая функция записи возвращает некоторое новое дерево состояний, а хранилище Redux уведомляет всех подписчиков, что дерево состояний было изменено.

Ключевым моментом здесь является то, что одна из функций «корень-редуктор» состоит из множества небольших функций, составленных вместе для выполнения работы. Итак, в некотором смысле есть только один слушатель, корневой редуктор. Но, в другом смысле, много слушателей, потому что функция корневого редуктора делегирует свои обязанности ряду других функций для выполнения реальной работы.

Я бы посоветовал вам внимательно ознакомиться с документами Redux. В частности, вы должны прочитать Reducers, Redux FAQ (в частности, раздел FAQ по адресу Reducers) и новый раздел Structuring Reducers. Обязательно прочтите некоторые из статей, перечисленных в Prerequisite Concepts.

+0

Тот же вопрос для вас, что и для Дейва; позже, когда отправляется RECEIVE_POSTS, я не понимаю, как вызываются «сообщения». Случай RECEIVE_POSTS: в postsBySubreddit не имеет никакой функции обработчика. – tito

+0

Функция 'postsBySubreddit' использует оператор switch для обработки всех трех случаев одинаково. Помните, что, ставя несколько случаев подряд, вы можете обрабатывать каждый из этих случаев одним и тем же кодом. Таким образом, все три случая (INVALIDATE_SUBREDDIT, RECEIVE_POSTS и REQUEST_POSTS) будут обрабатываться одинаково: путем вызова 'posts()' с данными для этой конкретной записи и текущего действия. – markerikson

+0

Я понял. Отличный ответ. Thanks – tito

0

Функциональность REQUEST_POSTS и RECEIVE_POSTS обрабатывается по каждому субредукту редуктором, называемым редуктором более высокого уровня.

, например, postsBySubreddit - это редуктор, открытый через combineReducers. Вместо того, чтобы поместить его функциональность в postsBySubreddit действие передается на posts редуктора, который устанавливает и получает только состояние для данного subreddit:

[action.subreddit]: posts(state[action.subreddit], action) 

Там нет никаких оснований подвергать posts редуктор в combineReducers; состояние обновляется субреддитом-эксклюзивным редуктором.

Все же логики может были обработаны в postsBySubreddit, но это сделало бы postsBySubreddit больше и грязнее. posts действует на (субреддитно-септический) срез состояния. Это просто разделение проблем.

Особенности:

  • Это называется каждым действием обрабатываемого postsBySubreddit
  • Это определяется отдельно, так что состояние нарезка обрабатывается в одном месте (postsBySubreddit) и subreddit конкретного государственного манипулирования обрабатывается в одном месте (posts)
  • На верхнем уровне postsBySubreddit видит действия - но эти сообщения делегируются posts, как и при любом другом рефакторинге.
+0

Я понимаю эту начальную часть, но позже, когда отправляется сообщение RECEIVE_POSTS, я не понимаю, как вызываются «сообщения». Случай RECEIVE_POSTS: в postsBySubreddit не имеет никакой функции обработчика. – tito

+1

@tito \t Уверен, похоже, что он делает; Заявления о делах JS проваливаются. –

+0

Спасибо Дэйв. Ваше объяснение было большим! – tito

Смежные вопросы