react-redux
react 和 redux 的使用
在之前使用 react 时,我们把数据放到 state,通过 setState 可以触发 react 的更新渲染,而目前状态数据都交由 redux 管理。redux 数据状态发生改变时,相应的是我们通过 subscribe 方法绑定的 listener。所以我们需要绑定一个比较合适的监听函数作为状态变化时的相应,react 提供了主动触发 react 更新渲染的方法 forceUpdate
。
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
const INCREMENT = 'INCREMENT'
const DECREMENT = 'DECREMENT'
const reducer = (state = 0, action) => {
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
default:
return state;
}
}
const store = createStore(reducer)
//展示组件
const Counter = ({
count, onIncrement, onDecrement }) => (
<div>
<h1>{count}</h1>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
)
// 容器组件
class CounterContainer extends React.Component {
componentDidMount() {
this.unsubscribe = store.subscribe( () => {
this.forceUpdate()
})
}
componentWillUnmount() {
this.unsubscribe()
}
render(){
return <Counter
count={ store.getState() }
onIncrement = { () => store.dispatch({type: INCREMENT}) }
onDecrement = { () => store.dispatch({type: DECREMENT}) }
/>
}
}
ReactDOM.render(<CounterContainer />,document.getElementById('root'))
React是构建用户界面的框架,而 Redux 是为了解决状态管理问题专门开发的库,两者适合搭配但使用不是必须。React 官方专门提供了连接 react 和 redux 的库,react-redux。react-redux 主要提供两个方法
- provider 是向整个应用传递store容器组件
- connect 方法可以更具用户展示组件自动生成对应容器组件
provider 就像我们传递 store 用的容器组件,一般都会套在应用组件的最外层。而 connect 方法可以根据我们现有的展示组件,自动生成容器组件。connect 需要传递2个参数。
- mapStateToProps,用来对应state和props,并且传入参数时,在我们redux发生改变时,就会自动触发组件的更新。
- mapDispatchToProps,通过dispatch来传递对应的方法来触发action事件。
connect在获取了 redux 的 store 之后,再更具我们传入的方法把我们需要的部分对应到 props 属性当中,再传递到我们的组件里。
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider ,connect } from 'react-redux'
import PropTypes from 'prop-types'
const INCREMENT = 'INCREMENT'
const DECREMENT = 'DECREMENT'
const Reducer = (state = 0, action) => {
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
default:
return state;
}
}
const store = createStore(Reducer)
//展示组件
const Counter = ({
count, onIncrement, onDecrement }) => (
<div>
<h1>{count}</h1>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
)
Counter.propTypes = {
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
const mapStateToProps = (state) => (
{
count:state
}
)
const mapDispatchToProps = (dispatch) => {
return {
onIncrement:()=>{
dispatch({ type: INCREMENT })
},
onDecrement:() => {
dispatch({type: DECREMENT})
}
}
}
// 容器组件
const CounterContainer = connect(mapStateToProps, mapDispatchToProps)(Counter)
ReactDOM.render(
<Provider store={store}>
<CounterContainer />
</Provider>
,document.getElementById('root'))
react-redux实现了很多优化,不会像 ReactDOM.render 和 foreUpdate 一样耗费效率,正式开发中建议使用 react-redux。