官方 redux reducer 示例不清楚
Official redux reducer example not clear
我正在尝试理解官方的 Redux reducer 示例。
我不确定是谁调用了这个 "posts" 函数,为什么单独定义它,为什么这个函数从未暴露给 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 时被调用。
在我看来,在这种情况下我们有多个侦听器来执行相同的操作。试图理解为什么。
REQUEST_POSTS
和 RECEIVE_POSTS
的功能由 "higher-level" 减速器调用的减速器处理每个子版块。
例如,postsBySubreddit
是通过 combineReducers
暴露的减速器。不是将其功能放入 postsBySubreddit
,而是将操作传递给 posts
reducer,它只设置和接收 给定 subreddit:[=27 的状态=]
[action.subreddit]: posts(state[action.subreddit], action)
没有理由在 combineReducers
中公开 posts
reducer;状态由 subreddit 专用的减速器更新。
所有相同的逻辑 可以 在 postsBySubreddit
中处理,但这会使 postsBySubreddit
更大更混乱。 posts
作用于状态的(特定于 subreddit 的)切片。这只是关注点的分离。
细节:
- 它被
postsBySubreddit
处理的每个动作调用
- 它是单独定义的,所以状态切片在一个地方处理 (
postsBySubreddit
),subreddit 特定的状态操作在一个地方处理 (posts
)
- 在顶层只有
postsBySubreddit
可以看到操作——但是这些消息被委托给 posts
与任何其他重构一样。
posts
函数在postsBySubreddit()
函数内部被调用:
case REQUEST_POSTS:
return Object.assign({}, state, {
[action.subreddit]: posts(state[action.subreddit], action)
})
单独定义是为了明确逻辑是如何工作的。 postsBySubreddit
负责确定 哪个 subreddit 的数据应该更新,而 post
负责更新单个 subreddit 的数据。它实际上是关注点分离。这两个函数都知道如何更新一些数据以响应给定的操作。
引用自文档:
At its core, Redux is really a fairly simple design pattern: all your "write" logic goes into a single function, and the only way to run that logic is to give Redux a plain object that describes something that has happened. The Redux store calls that write logic function and passes in the current state tree and the descriptive object, the write logic function returns some new state tree, and the Redux store notifies any subscribers that the state tree has changed.
这里的关键是一个 "root reducer" 函数本身由许多小函数组成,这些函数组合在一起完成工作。因此,从某种意义上说,只有一个侦听器,即根减速器。但是,从另一个意义上说,有很多听众,因为根 reducer 函数将其职责委托给许多其他函数来完成真正的工作。
我鼓励您通读 Redux 文档。特别是,您还应该阅读 Reducers, the Redux FAQ (particularly the FAQ section on Reducers ) and the new Structuring Reducers section. Be sure to read through some of the articles listed in Prerequisite Concepts。
我正在尝试理解官方的 Redux reducer 示例。
我不确定是谁调用了这个 "posts" 函数,为什么单独定义它,为什么这个函数从未暴露给 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 时被调用。
在我看来,在这种情况下我们有多个侦听器来执行相同的操作。试图理解为什么。
REQUEST_POSTS
和 RECEIVE_POSTS
的功能由 "higher-level" 减速器调用的减速器处理每个子版块。
例如,postsBySubreddit
是通过 combineReducers
暴露的减速器。不是将其功能放入 postsBySubreddit
,而是将操作传递给 posts
reducer,它只设置和接收 给定 subreddit:[=27 的状态=]
[action.subreddit]: posts(state[action.subreddit], action)
没有理由在 combineReducers
中公开 posts
reducer;状态由 subreddit 专用的减速器更新。
所有相同的逻辑 可以 在 postsBySubreddit
中处理,但这会使 postsBySubreddit
更大更混乱。 posts
作用于状态的(特定于 subreddit 的)切片。这只是关注点的分离。
细节:
- 它被
postsBySubreddit
处理的每个动作调用
- 它是单独定义的,所以状态切片在一个地方处理 (
postsBySubreddit
),subreddit 特定的状态操作在一个地方处理 (posts
) - 在顶层只有
postsBySubreddit
可以看到操作——但是这些消息被委托给posts
与任何其他重构一样。
posts
函数在postsBySubreddit()
函数内部被调用:
case REQUEST_POSTS:
return Object.assign({}, state, {
[action.subreddit]: posts(state[action.subreddit], action)
})
单独定义是为了明确逻辑是如何工作的。 postsBySubreddit
负责确定 哪个 subreddit 的数据应该更新,而 post
负责更新单个 subreddit 的数据。它实际上是关注点分离。这两个函数都知道如何更新一些数据以响应给定的操作。
引用自文档:
At its core, Redux is really a fairly simple design pattern: all your "write" logic goes into a single function, and the only way to run that logic is to give Redux a plain object that describes something that has happened. The Redux store calls that write logic function and passes in the current state tree and the descriptive object, the write logic function returns some new state tree, and the Redux store notifies any subscribers that the state tree has changed.
这里的关键是一个 "root reducer" 函数本身由许多小函数组成,这些函数组合在一起完成工作。因此,从某种意义上说,只有一个侦听器,即根减速器。但是,从另一个意义上说,有很多听众,因为根 reducer 函数将其职责委托给许多其他函数来完成真正的工作。
我鼓励您通读 Redux 文档。特别是,您还应该阅读 Reducers, the Redux FAQ (particularly the FAQ section on Reducers ) and the new Structuring Reducers section. Be sure to read through some of the articles listed in Prerequisite Concepts。