React-Redux
Redux实现了一个store作为数据存储中心,可以供外部访问,修改等,这就是Redux的思想。但是Redux本身是和React没什么本质联系,只不过Redux的这种数据管理方式和React的数据驱动视图理念很合拍。
现在既然有了一个安全的地方存取数据,怎么结合到React里面呢?我们可以在应用初始化的时候,创建一个store = createStore(reducer),然后在需要的地方通过store.getState()去获取数据,通过store.dispatch去更新数据,通过store.subscribe去订阅数据变化然后进行setState…如果很多地方都这样做一遍,实在是不堪其重,而且,还是没有避免掉全局变量的不优雅。
由于全局变量有诸多的缺点,那就换个思路,把store直接集成到React应用的顶层props里面,只要各个子组件能访问到顶层props就行了。
实际上React-Redux提供了几个高阶组件,来看一下。
1.provider
React-Redux提供了Provider组件,通过该组件可以向其子组件,孙组件传递store,而不用每个组件手动引入。
index.js文件
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {
Provider } from "react-redux";
import store from "./store";
ReactDOM.render(
<Provider store={
store}>
<App />
</Provider>,
document.getElementById('root')
);
2.connect
connect方法能够把组件和store连接起来,这样就可从redux store中读取数据,以及在store更新后重新读取数据。
import {
connect } from "react-redux";
const Counter = (props) => {
const {
num, sum, ADD, MINUS, SUM_ADD, SUM_MINUS} = props
return (
<div>
<p>{
num}</p>
<button onClick={
ADD}>+</button>
<button onClick={
MINUS}>-</button>
<p>{
sum}</p>
<button onClick={
SUM_ADD}>+</button>
<button onClick={
SUM_MINUS}>-</button>
</div>
)
}
const mapStateToProps = (state, ownProps) => {
const {
count } = state.countReducer;
const {
sum } = state.sumReducer;
return {
num: count,
sum: sum
};
};
const mapDispatchToProps = (dispatch, ownProps) => {
return {
ADD: () =>
dispatch({
type: "ADD"
}),
MINUS: () =>
dispatch({
type: "MINUS"
}),
SUM_ADD: () =>
dispatch({
type: "SUM_ADD"
}),
SUM_MINUS: () =>
dispatch({
type: "SUM_MINUS"
})
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
之前的store.js不用修改,结果如图:
connect接收两个参数,都是可选参数:
- mapStateToProps:每当store state发生变化时就会调用,接收整个store,并且返回一个该组件所需要的数据对象
- mapDispatchToProps:这个参数可以是一个函数或对象。
- 如果是一个函数,一旦该组件被创建,就会被调用。接收disparch作为一个参数,并且返回一个能够使用dispatch来分发actions的若干函数组成的对象
- 如果是一个action creators构成的对象,每一个action creator将会转化为一个prop function,并且在调用时自动分发actions。注意:推荐使用这种形式