react-redux的原理
react-redux
的设计理念,是增加一个容器组件,把组件和store
之间的通信分成两部分:第一部分是用容器组件来获取store中的数据和方法,另一部分是容器组件通过props把这些数据和方法传递给子组件:
第一步:创建容器组件
import { connect } from 'react-redux'
import CountUI from "../../components/Count";
import {increment, decrement, incrementAsync} from "../../redux/actions/count";
export default connect(
state => ({
count: state.count,
personCount: state.person.length
}),
dispatch => ({
increment: data => dispatch(increment(data)),
decrement: data => dispatch(decrement(data)),
incrementAsync: data => dispatch(incrementAsync(data)),
})
)(CountUI);
- 下载依赖
yarn add react-redux
; - 在容器组件中引入
connect
,创建父组件并暴露;在App.js
中引入父组件; -
connect
是个高阶函数,第一次调用的参数是两个函数,第二次调用的参数是子组件:
(1)第一次调用的第一个函数参数,带默认参数state,返回值为子组件中要使用的状态数据,key和value分别作为props中的key-value传递。
(2)第一次调用的第二个函数参数,带默认参数dispatch,返回值为修改数据的方法。可以省略重复的结构简写为对象形式:
import { connect } from 'react-redux'
import CountUI from "../../components/Count";
import {increment, decrement, incrementAsync} from "../../redux/actions/count";
export default connect(
state => ({
count: state.count,
personCount: state.person.length
}),
// dispatch => ({
// increment: data => dispatch(increment(data)),
// decrement: data => dispatch(decrement(data)),
// incrementAsync: data => dispatch(incrementAsync(data)),
// })
{ increment, decrement, incrementAsync}
)(CountUI);
- 容器组件可以和子组件合二为一:
import React, {Component} from "react";
import {connect} from "react-redux";
import {
increment,
incrementAsync,
decrement
} from "../../redux/actions/count";
class Count extends Component{
increment = () => {
const {value} = this.selectDom;
this.props.increment(value * 1);
}
...
render() {
return (
<div>
<h2>当前求和为{this.props.count}</h2>
<h2>下面人数为{this.props.personCount}</h2>
<select ref={c=>this.selectDom = c}>
{[1,2,3].map((number, i) => <option value={number} key={i}>{number}</option>)}
</select>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<button onClick={this.incrementIfOdd}>求和为奇数则加</button>
<button onClick={this.incrementAsync}>异步求和</button>
</div>
)
}
}
export default connect(
state => ({
count: state.count,
personCount: state.person.length
}),
{ increment, decrement, incrementAsync}
)(Count);
第二步:给父容器传入store
react-redux
中,父容器给子组件传入store中的数据,需要确保给父容器传入了store
:
import React, {Component} from 'react';
import Count from "./container/Count";
import Person from "./container/Person";
import store from "./redux/store";
export default class App extends Component{
render() {
return (
<div>
{/**
react-redux 需要给容器组件传入store
*/}
<Count store = {store}/>
<hr/>
<Person store = {store}/>
</div>
);
}
}
但是这样给 App中的所有父容器一一传入store
比较麻烦,可以借助react-redux
提供的 Provider
组件,给App中所有的容器组件传入store
:
src/index.js
import React from "react";
import ReactDom from 'react-dom';
import App from './App';
import store from "./redux/store";
import { Provider } from 'react-redux';
/**
* 从react-redux中引入Provider,在入口文件中包裹App,传入store,则App下的所有容器都会包含store这个props
* */
ReactDom.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root'));
- 使用
react-redux
可以不用手动监听store
改变触发渲染了。