# react-redux
React Redux is the official React binding for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update data.
主要就是解决监听store的变化,然后更新组件。
同时可以获取到store中的state,和派发action的能力,也就是dispatch函数。
# 有2个重要的api
- Provider
就是利用context传递store。
import { Provider } from "react-redux";
<Provider store={store}>
// 被包裹并且connected子组件可以获取store中的 state 和 dispatch函数。
</Provider>
- connect
利用高阶组件,监听store变化,传递state,dispatch给组件。
import { connect } from "react-redux";
# 如何使用
const App = (props)=>{
const { someProp, someAction } = props;
return (
<div>
{someProp}
<button onClick={someAction}>click</button>
</div>
);
}
const mapStateToProps = (state)=> ({
someProp: state.someProp
})
// 返回一个function,这个function返回一个object
const mapDispatchToProps = (dispatch) => ({
someAction: dispatch(actionCreator())
})
// 官方推荐的写法
// 返回一个object,每个key都是actionCreator函数
const mapDispatchToProps = ({
actionCreator
})
export default connect(mapStateToProps, mapDispatchToProps)(App);
# connect 的原理
import React from 'react';
import PropTypes from 'prop-types'
import { bindActionCreators } from 'redux';
export const connect = (
mapStateToProps = state => state,
mapDispatchToProps = {}
) => WrapComponent => {
return class ConnectComponent extends React.Component {
static contextTypes = { store: PropTypes.object };
constructor(props, context) {
super(props, context);
this.state = { props: {} };
}
componentDidMount() {
const { store } = this.context;
store.subscribe(() => this.update());
this.update();
}
update() {
const { store } = this.context;
const stateProps = mapStateToProps(store.getState());
const dispatchProps = bindActionCreators(mapDispatchToProps, store.dispatch);
this.setState({ props: { ...this.state.props, ...stateProps, ...dispatchProps } });
}
render() {
return <WrapComponent {...this.state.props}></WrapComponent>;
}
};
};
connect:
- 自动订阅store。
- 返回一个高阶组件。
- 什么时候被包裹的组件 re-render
表头 | (state) => stateProps | (state, ownProps) => stateProps |
---|---|---|
mapStateToProps runs when: | store state changes | store state changes or any field of ownProps is different |
component re-renders when: | any field of stateProps is different | any field of stateProps is different or any field of ownProps is different |
- 使用reselect 缓存 mapStateToProps的结果。
# Provider的实现原理
import React from 'react'
import PropTypes from 'prop-types'
export class Provider extends React.Component {
// 需要声明静态属性childContextTypes来指定context对象的属性,是context的固定写法
static childContextTypes = {
store: PropTypes.object
}
// 实现getChildContext方法,返回context对象,也是固定写法
getChildContext() {
return { store: this.store }
}
constructor(props, context) {
super(props, context)
this.store = props.store
}
// 渲染被Provider包裹的组件
render() {
return this.props.children
}
}