基于【React.js 07】React中使用Redux所举的例子(后面两篇08、09的文章案例有所修改,也都贴上了代码),我们是手动连接的
React
和Redux
,这一篇我们将其改为自动连接的。
文中案例接上一篇的案例,代码都有贴上了。
我们要把Redux
和React
优雅的结合起来,使用自动连接,免除了手动连接的烦恼;因为一旦组件的深度极深时,那么就会出现层层传递store
属性的陷阱中,非常棘手。
为了把Redux
和React
优雅的结合起来实现自动连接,我们使用react-redux
库来实现。
安装:
npm install react-redux --save
使用:
安装完毕后,很简单,只需要忘记subscribe
,记住reducer
、action
、dispatch
即可。
react-redux
提供了两个新的接口Provider
和connect
来连接。
第一步:
作为应用的最外层,index.js
要引入Provider接口
import { Provider } from 'react-redux'
Provider
组件在应用的最外层,传入store
即可,只用一次,同时原来传递的其他参数(例如执行的方法)也不用传了,并且不用subscribe
了,不需要subscribe
,也就意味不需要去封装ReactDom.render()
方法了:
ReactDom.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
第二步:
connect在组件里面负责从外部获得组件所需要的参数,在组件App.js
中引入connect
import { connect } from 'react-redux'
组件中,把所需要的状态映射到属性上:
//状态映射属性
const mapStatetoProps = (state)=>{
//需要哪些状态数据
return {num : state}
}
上面所说的num
原来是由store.getState()
获取到的,那么此时因为最外层使用了Provider
,store
只需要传一次,并且是传给Provider
的,所以这里也就不再有store
这个属性了,num
的定义也就不需要了。
再把所需要的方法也组成一个对象:
//先引入需要的方法
import { hire, hireAsync ,fire } from './index.redux'
//需要执行的方法组成一个对象
const actionCreator = { hire, hireAsync ,fire }
在组件类写完后,connect
则作为装饰器传入对应的类并生成一个新的类返回:
App = connect(mapStatetoProps ,actionCreator)(App)
相当于所有状态、方法都被当成属性塞进App
里面了,这样执行的事件也变成了属性:
<p onClick={this.props.hire}>雇佣一人</p>
<p onClick={this.props.hireAsync}>雇佣一人,晚两天到</p>
<p onClick={this.props.fire}>开除一人</p>
这样
React
和Redux
也就自动连接了起来,不用再一直传递store
了。
上代码:(因为案例中仅修改index.js
以及App.js
文件)
./src/index.js
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import { createStore ,applyMiddleware ,compose} from 'redux'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import { manageCompany } from './index.redux'
const reduxDevtools = window.devToolsExtension ? window.devToolsExtension() : ()=>{}
// 通过reducer创建store,通过compose把几个函数组合起来
const store = createStore(manageCompany, compose(
applyMiddleware(thunk),
reduxDevtools
))
ReactDom.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
./src/App.js
import React , { Component } from 'react'
import { connect } from 'react-redux'
import { hire, hireAsync ,fire } from './index.redux'
class App extends Component {
render() {
return (
<div>
<h1>公司现在有{this.props.num}人</h1>
<p onClick={this.props.hire}>雇佣一人</p>
<p onClick={this.props.hireAsync}>雇佣一人,晚两天到</p>
<p onClick={this.props.fire}>开除一人</p>
</div>
)
}
}
//状态映射属性
const mapStatetoProps = (state)=>{
//需要哪些状态数据
return {num : state}
}
//需要执行的方法
const actionCreator = { hire, hireAsync ,fire }
App = connect(mapStatetoProps ,actionCreator)(App)
export default App
网友评论