react-redux

React 和 Redux没有直接关系,但是二者都是通过state来描述界面的状态,因此redux可以和react很好地结合使用

React-Redux将所有组件分成两大类:UI组件和容器组件,UI组件负责页面的呈现,容器组件负责管理数据和逻辑

UI组件的特征:

  1. 只负责UI的呈现,不带有任何业务逻辑
  2. 没有状态(不使用this.state这个变量)
  3. 所有数据都由参数(this.props)提供
  4. 不使用任何Redux的API

容器组件的特征:

  1. 负责管理数据和业务逻辑,不负责UI的呈现
  2. 带有内部状态
  3. 使用Redux的API

如果一个组件既有UI又有业务逻辑,则可以将其拆分成这样的结构:

  • 外面是一个容器组件,里面包含一个UI组件
  • 外面的容器组件负责与外部的通信,将数据传给里面的UI组件,然后UI组件渲染出视图

connect()方法:Redux提供connect方法,用于从UI组件生成容器组件

import { connect } from 'react-redux'
const VisibleTodoList = connect()(TodoList)    //TodoList是UI组件,VisibleTodoList是react-redux通过connect方法生成的容器组件

该容器组件包含以下两部分的业务逻辑:

  1. 输入逻辑:外部的数据(state对象)如何转换为UI组件的参数
  2. 输出逻辑:用户发出的动作如何变为action对象,从UI组件转出去
import { connect } from 'react-redux'
const VisibleTodoList = connect(       //connect方法接收两个参数:mapStateToProps 和 mapDispatchToProps
  mapStateToProps,                     //负责输入逻辑,将state映射到UI组件的参数(props) 
  mapDispatchToProps                   //负责输出逻辑,将用户对UI组件的操作映射成action
)(TodoList)

mapStateToProps方法:建立从state对象到UI组件的props的映射关系

const mapStateToProps = (state) => {     
  return{                              //mapStateToProps函数返回一个对象
    todos:state.todos                  //返回的对象有一个todos属性,对应UI组件的同名参数
  }
}

mapStateToProps方法会订阅store,每当state更新的时候,就会自动执行,重新计算UI组件的参数,从而触发UI组件的重新渲染

mapDispatchToProps方法:建立UI组件的参数到store.dispatch方法的映射,即定义哪些用户的操作应该当作action,传给store

const mapDispatchToProps = (dispatch) => {
  return{          //返回一个对象,对象的每个键值对都是一个映射,定义了UI组件的参数怎样发出action
    increment: () => { dispatch(increment()) }
  }
}

<Provider>组件

connect方法生成容器组件后,需要让容器组件拿到state对象,才能生成UI组件的参数

React-Redux提供Provider组件,可以让容器组件拿到state

import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from './reducer'
import App from './App'

let store = createStore(reducer)

render(
  <Provider store={store}>     //Provider组件中包含了App组件,使得App组件的所有子组件也可以拿到state
    <App/>
  </Provider>,
  document.getElementById('root')
)

实例:计数器

  创建Counter组件

import React from 'react'
import { connect } from 'react-redux'
import incrementAction from '../redux/actions/actionCreators'

export default class Counter extends React.Component{
    render(){
        const { value,increment } = this.props       
        return(
            <div>
               <span>{value}</span>
               <br/>
               <button onClick={increment}>+</button>
            </div>
        )
    }
}

   该UI组件的参数:

//定义从state到value的映射
const mapStateToProps = (state) => {
    return{
        value:state.count
    }
}
//定义从increment到dispatch的映射
const mapDispatchToProps = (dispatch) => {
    return{
        increment:()=>{
            dispatch(incrementAction)
        }
    }
}

  使用connect方法生成容器组件:

export default connect(mapStateToProps,mapDispatchToProps)(Counter)

  对代码拆分:将store、reducer、action拆分成一个个文件,放到store文件夹中

     store/reducer.js

function counter(state={count:0},action){
    const count = state.count
    switch(action.type){
        case 'increment':
            return {count:count+1};
        default:
            return state;
    }
}
export default counter

    store/index.js

import { createStore } from 'redux'
import reducer from './reducer/reducer'

const store = createStore(reducer);
export default store;

      store/actionCreations.js

const incrementAction = {
    type:'increment'
}
export default incrementAction

  使用Provider组件:

ReactDOM.render(
  <Provider store={store}>
      <Counter/>
  </Provider>,
  document.getElementById('root')
);  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值