美文网首页
React-Redux

React-Redux

作者: 行走的蛋白质 | 来源:发表于2020-01-20 17:11 被阅读0次
    UI 组件和容器组件
    • React-Redux 将所有组件分为两大类:UI ( presentational component ) 组件和容器 ( container component ) 组件
    • UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
    • 如果一个组件既有 UI 又有业务逻辑则将其进行拆分:外面是一个容器组件,里面是一个 UI 组件,前者负责与外部的通信将数据传给后者,由后者渲染出视图。
    • React-Redux 规定:所有 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说用户负责视图层, 状态管理则是全部交给它。
    /*
    * UI 组件
    * 只负责 UI 的呈现,不带有任何业务逻辑
    * 没有状态 --- 不使用 this.state 这个变量
    * 所有数据由参数 this.props 提供
    * 不使用任何 Redux 的 API
    */
    const Titile = (value) => <h2>{ value }</h2>
    
    /*
    * 容器组件
    * 负责管理数据和业务逻辑
    * 带有内部状态
    * 使用 Redux 的 API
    */
    
    connect()
    • 用于从 UI 组件生成容器组件
    import { connect } from 'react-redux'
    const VisibilityTodoList = connect({
        mapStateToProps,
        mapDispatchToProps
    })(TodoList)
    
    • 接收的两个参数 mapStateToProps 和 mapDispatchToProps 定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将 state 映射到 UI 组件的参数 props;后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
    mapStateToProps
    • 建立一个从 ( 外部的 ) state 对象到 ( UI 组件的 ) props 对象的映射关系
    • 它执行后返回一个对象,里面的每一个键值对就是一个映射,如下:
    const mapStateToProps = state => ({
        todos: getVisibleTodos(state.todos, state.visibilityFilter)
    })
    

    注解:如上 mapStateToProps 是一个函数,它接收 state 作为参数,返回一个对象。这个对象有一个 todos 属性,代表 UI 组件的同名参数,后面的 getVisibleTodos 函数根据 state 来计算出 todos 的值示例如下:

    const getVisibleTodos = (todos, filter) => {
        switch(filter) {
            case VisibilityFilters.SHOW_ALL:
                return todos
            case VisibilityFilters.SHOW_COMPLETED:
                return todos.filter(v => v.completed)
            case VisibilityFilters.SHOW_ACTIVE:
                return todos.filter(v => !v.completed)
            default: 
                throw new Error(`Unknown filter: ${filter}`)
        }
    }
    
    • mapStateToProps 会订阅 Store,每当 state 更新的时候,就会自动执行,重新来计算 UI 组件的参数,来触发 UI 组件的重新渲染。
    • mapStateToProps还会接收第二个参数,代表容器组件的 props 对象:
    const mapStateToProps = (state, ownProps) => ({
        active: ownProps.filter === state.visibilityFilter
    })
    
    • 使用 ownProps 作为参数后,如果容器组件的参数发生变化也会引起 UI 组件的重新渲染
    • connect 方法可以省略 mapStateToProps 参数,这样的话 UI 组件就不会订阅 Store,那么 Store 的更新就不会引起 UI 组件的更新
    mapDispatchToProps
    • 它是 connect 的第二个参数,用来建立 UI 组件参数到 store.dispatch 方法的映射,它定义了哪些用户的操作应该当做 Action 传给 Store,它可以是一个函数也可以是一个对象
    // 1.作为函数,接收 dispatch,ownPros ( 容器组件的 props 对象 ) 两个参数。
    // 作为函数,返回一个对象,对象的每个键值对都是一个映射,定义了 UI 组件的参数应该怎样发出 Action
    const mapDispatchToProps = (dispatch, ownProps) => {
        return {
            onClick: () => {
                dispatch({
                    type: 'SET_VISIBILITY_FILTER',
                    filter: ownProps.filter
                })
            }
        }
    }
    
    // 2.作为对象,键名也是对应 UI 组件的同名参数
    // 键值是一个函数被当做 Action creator 返回的 action 由 Redux 自动发出
    const mapDispatchToProps = {
        onClick: (filter) => {
            type: 'SET_VISIBILITY_FILTER',
            filter: filter
        }
    }
    
    Provider 组件
    • connect 方法生成容器组件以后,需要让容器组件拿到 state 对象,才能生成 UI 组件的参数
    • React-Redux 提供 Provider 组件可以让容器组件拿到 state
    import React from 'react'
    import { render } from 'react-dom'
    import { createStore } from 'redux'
    import { Provider } from 'react-redux'
    import App from './components/App'
    import rootReducer from './reducers'
    
    const store = createStore(rootReducer)
    
    render(
        <Provider store={store}>
            <App />
        </Provider>,
        document.getElementById('root')
    )
    

    如上:Provider 在根组件外面包了一层,这样 App 所有子组件都能默认拿到 state 了

    文章内容学习自阮一峰老师的:Redux 入门教程(三):React-Redux 的用法

    相关文章

      网友评论

          本文标题:React-Redux

          本文链接:https://www.haomeiwen.com/subject/zqwhzctx.html