2-react与 redux 的链接

2018-06-06  本文已影响0人  谷子多
屏幕快照 2018-06-25 下午3.23.21.png
屏幕快照 2018-06-26 下午4.28.00.png

步骤:

1. 下载

    npm install --save react-redux

2、引入connect

    import  {connect} from 'react-redux'

connect是一个高阶组件:首先需要传一些数据过去,接着在运行完成之后会得到一个函数,这个函数就是一个高阶组件,通过这个函数将组件传进去你就会得到一个新的组件,这个所以这个文件最后需要导出的是connect。

3、引入react-redux

import {
    Provider,
    connect
} from 'react-redux'

4、将Provider放置在根元素

注意:必须要有一个child

ReactDOM.render(
    <Provider>
       <Counter></Counter> 
    </Provider>,
   
    document.getElementById('root')
)

这个时候,在组件的render里面打印this.props,就可以得到dispatch,这就是真正的sotere.dispatch。

这个dispacth是谁传过来的?
是Provider,通过props绑定了store,通过store.dispatch得到了一个方法,得到这个方法之后,绑定到了connect的API上,props是一级一级传递。

5、connect

connect([mapStateToProps],[mapDispatchToProps])
//通过字面意思可以理解:第一个参数是将state传到了props,第二个参数是将dispatch传到了props

第一个参数:函数,里面必须return一个对象。
在这第一个参数的函数里,return出来了什么,这个组件的props就会得到什么。
这个时候在控制台打印this.props,就会得到:{a: 1, b: 2, dispatch: ƒ}

export default connect(
    ()=>{
        return {
            a:1,
            b:2
        }
    }
)(Counter)

我们再传入第二个参数:

export default connect(
    ()=>{
        return {
            a:1,
            b:2
        }
    },
    ()=>{
        return {
            c : 888
        }
    }
)(Counter)

这时候控制台打印props,得到 : {a: 1, b: 2, c: 888},可以看到:dispatch没有了,但是这时候定义的c:888被组合到了props里面。

这样做有什么意义?意义就在于接收的参数,第一个函数的参数是state,这就是store.getState()的state,第二个函数的参数是dispatch,就是dispatch一个action的,也就是第一个参数是getState拿数据,第二个参数是dispatch改数据,
如何提交action呢?

6、

新建一个文件,里面放置action,并将这几个action导出(只要actionCreators)。
如果某个actionCreator是通过中间件创建的,那么得到的就是一个函数,而不是一个对象,所以这时候如果想用这个actionCreator,就需要引入中间件,比如以下下面这个actionCreator:

let increaseByAsyncAction = (val)=>(dispatch,getState)=>{
    setTimeout(()=>{
        dispatch(decreaseAction(val))
    },1000)
}

这时候就需要在index,即需要提交action的文件里引入redux-thunk

import thunk from 'redux-thunk' 
const store = createStore(counter,0,applyMiddleware(thunk),0)

7、使用react-redux提交aciton

 render(){
        console.log(this.props)
//第一步,首先需要取出state和dispatch
        let {count,dispatch} = this.props
        return(
            <div>
                <button className="decrease" 
//然后就可以dispatch对应的action
                    onClick={()=>{
                        dispatch(countActions.decreaseAction(1))
                    }}>-</button>
                <span>{count}</span>
                <button className="increase"
                    onClick={()=>{
                        dispatch(countActions.increaseAction(1))
                    }}
                >+</button>
                <button className="odd">in by odd</button>
                <button className="async">in by async</button>
            </div>
        )
    }   

疑问?监听器在哪里执行的
其实是写在了Provider里面,这个组件绑定了props:strore,这是最顶层的组件,一旦监听到state的变化,就会setState,然后所有的子组件都会更新,这时候就得到了新的props状态。所以这就是把Provider写在最顶层的原因。

8、简写

现在写了很多手动提交的dispatch,有没有一种方法而已简写呢?

  1. 引入
  import {bindActionCreators} from 'redux'
// 已经绑定好了action,所以直接b.decreaseAction即可,返回一个对象{decreaseAction,increaseAction}
  let b = bindActionCreators(countActions,dispatch)
<button className="decrease" 
  onClick={()=>{
  b.decreaseAction(1)
}}>-</button>
  1. 可以将这个bindActionCreators传到第二个参数函数中,这样就会发送到props,就可以解构直接使用了。
export default connect(
    (state)=>{ //store.getState()
        return {
            count : state
        }
    },
    (dispatch)=>bindActionCreators(countActions,dispatch)
)(Counter)

let {count,decreaseAction,increaseAction} = this.props

import React,{Component} from 'react'
import {connect} from 'react-redux'
import countActions from '../actions/countAction'
import {bindActionCreators} from 'redux'

class Counter extends Component{
    constructor(props){
        super(props)
    }
    render(){
        console.log(this.props)
        let {count,decreaseAction,increaseAction} = this.props
        // 已经绑定好了action,所以直接b.decreaseAction即可,返回一个对象{decreaseAction,increaseAction}
        //let b = bindActionCreators(countActions,dispatch)
        return(
            <div>
                <button className="decrease" 
                    onClick={()=>{
                        decreaseAction(1)
                    }}>-</button>
                <span>{count}</span>
                <button className="increase"
                    onClick={()=>{
                       increaseAction(1)
                    }}
                >+</button>
                <button className="odd">in by odd</button>
                <button className="async">in by async</button>
            </div>
        )
    }   
}


export default connect(
    (state)=>{ //store.getState()
        return {
            count : state
        }
    },
    (dispatch)=>bindActionCreators(countActions,dispatch)
)(Counter)
上一篇下一篇

猜你喜欢

热点阅读