我覺得你的困惑是那部分reducer composition和selectors。
讓我們從相反的UI開始,以相反的順序來看它。
在連接部件containers/VisibleTodoList.js它從「狀態」(的redux
全局存儲對象)的內部mapStateToProps
得到todos
,而使其通過的getVisibleTodos
方法。
可以稱之爲一個選擇器,因爲它選擇並僅返回其接收到的數據的一部分:
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
case 'SHOW_ALL':
default:
return todos
}
}
const mapStateToProps = state => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id))
}
}
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
的state
(Redux的商店)傳遞給mapStateToProps
從根減速器reducers/index.js來到和實際上是一個單減速器(對象),其經由combineReducers
效用的redux
代表所有其他減速器的組合:
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
const todoApp = combineReducers({
todos,
visibilityFilter
})
export default todoApp
正如可以看到的,todos
減速機在那裏。所以這就是爲什麼在mapStateToProps
裏我們把它叫做這個state.todos
。
這裏是reducers/todos.js:
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
case 'TOGGLE_TODO':
return state.map(todo =>
(todo.id === action.id)
? {...todo, completed: !todo.completed}
: todo
)
default:
return state
}
}
export default todos
在'ADD_TODO'
類型的每個動作會返回一個新的狀態,新的todo
:
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
它裏面actions/index.js這個行動的創建者:
let nextTodoId = 0
export const addTodo = text => {
return {
type: 'ADD_TODO',
id: nextTodoId++,
text
}
}
So h ere是redux
的全部流程(我省略了調用動作的按鈕,因爲我認爲這對你來說是顯而易見的部分)。
好,幾乎全流,沒有這種可能發生而不Provider
HOC封裝了App
並注入實體店就在index.js:
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
let store = createStore(todoApp)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
現在,當redux
state
變化,mapStateToProps
通話被調用,將返回新映射的props
。 connect
將通過這些新的props
,這將觸發一個新的render
調用(實際上整個反應生命週期流)到連接的組件。
這種方式將使用來自商店的新數據重新呈現用戶界面。
看看'mapStateToProps'函數,這是你失蹤的最後一塊。它會從redux狀態更新組件的道具,從而在狀態更改時觸發重新渲染。 – xDreamCoding