官网demo https://github.com/reduxjs/redux/blob/master/examples/todos/src/index.js

image.png

目录结构

image.png

页面

/src/index.js

  1. // /src/index.js
  2. import React from 'react'
  3. import { render } from 'react-dom'
  4. import { createStore } from 'redux'
  5. import { Provider } from 'react-redux'
  6. import App from './components/App'
  7. import rootReducer from './reducers'
  8. const store = createStore(rootReducer)
  9. render(
  10. /**
  11. * Provider
  12. * https://www.redux.org.cn/docs/react-redux/api.html
  13. */
  14. <Provider store={store}>
  15. <App />
  16. </Provider>,
  17. document.getElementById('root')
  18. )

<Provider store> 使组件层级中的 connect() 方法能够获得 Redux store。

/src/components/App.js

  1. // /src/components/App.js
  2. import React from 'react'
  3. import Footer from './Footer'
  4. import AddTodo from '../containers/AddTodo'
  5. import VisibleTodoList from '../containers/VisibleTodoList'
  6. const App = () => (
  7. <div>
  8. <AddTodo />
  9. <VisibleTodoList />
  10. <Footer />
  11. </div>
  12. )
  13. export default App

把上中下拆分成了三个组件,挨个查看

/src/containers/AddTodo.js

  1. // /src/containers/AddTodo.js
  2. import React from 'react'
  3. import { connect } from 'react-redux'
  4. import { addTodo } from '../actions'
  5. const AddTodo = ({ dispatch }) => {
  6. let input
  7. return (
  8. <div>
  9. <form onSubmit={e => {
  10. e.preventDefault()
  11. if (!input.value.trim()) {
  12. return
  13. }
  14. dispatch(addTodo(input.value))
  15. input.value = ''
  16. }}>
  17. <input ref={node => input = node} />
  18. <button type="submit">
  19. Add Todo
  20. </button>
  21. </form>
  22. </div>
  23. )
  24. }
  25. export default connect()(AddTodo)

关于connect()(AddTodo)
函数将被调用两次。第一次是设置参数,第二次是组件与 Redux store 连接:connect(mapStateToProps,mapDispatchToProps, mergeProps)(MyComponent)
https://www.redux.org.cn/docs/react-redux/api.html
可以参考下边部分的Examples内容
image.png

/src/containers/VisibleTodoList.js

  1. // /src/containers/VisibleTodoList.js
  2. import { connect } from 'react-redux'
  3. import { toggleTodo } from '../actions'
  4. import TodoList from '../components/TodoList'
  5. import { VisibilityFilters } from '../actions'
  6. const getVisibleTodos = (todos, filter) => {
  7. switch (filter) {
  8. case VisibilityFilters.SHOW_ALL:
  9. return todos
  10. case VisibilityFilters.SHOW_COMPLETED:
  11. return todos.filter(t => t.completed)
  12. case VisibilityFilters.SHOW_ACTIVE:
  13. return todos.filter(t => !t.completed)
  14. default:
  15. throw new Error('Unknown filter: ' + filter)
  16. }
  17. }
  18. const mapStateToProps = state => ({
  19. todos: getVisibleTodos(state.todos, state.visibilityFilter)
  20. })
  21. const mapDispatchToProps = dispatch => ({
  22. toggleTodo: id => dispatch(toggleTodo(id))
  23. })
  24. export default connect(
  25. mapStateToProps,
  26. mapDispatchToProps
  27. )(TodoList)

任何时候,只要 Redux store 发生改变,mapStateToProps 函数就会被调用,该回调函数必须返回一个纯对象,然后再执行后边的(TodoList),这个对象会与组件的 props 合并。