我觉得你的困惑是那部分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