这块代码看好久没懂,求解。
redux action、store、reducer差不多理解,但是不知道这块代码有什么用,为什么这么写?
这块代码看好久没懂,求解。
redux action、store、reducer差不多理解,但是不知道这块代码有什么用,为什么这么写?
首先你要知道React组件的state和props的区别,然后redux的store就是一个巨大的外部状态,connect就是把这个状态和react组件的props关联起来。(先不考虑dispatch,原理是一样的)
如果你会typescript就更好理解了,以经典的计数器组件为例,没有redux的时候,你要自己维护状态(state):
interface OwnProps {} // 自己没有props
interface OwnState { // 自己维护了状态
count: number
}
class Counter extends React.Component<OwnProps , OwnState> {
constructor() {
super();
this.state = {count: 0}
}
render () {
return <h1>Count: {this.state.count}</h1>;
}
}
当你把状态移到redux,组件可以就不自己维护状态了:
interface OwnProps {} // 自己的props,没东西
interface OwnState {} // 自己维护的状态,没东西
interface ConnectedState { // 从redux传来的状态
count: number
}
type CounterProps = ConnectedState & OwnProps; // 实际的props是自己的props加上从redux传来的状态的结合
class Counter extends React.Component<CounterProps, OwnState> {
render () {
return <h1>Count: {this.props.count}</h1>;
}
}
上面应该很好理解,那么connect
怎样把redux的状态传给到组件呢,通过自定义的函数把redux的state映射(map)到合适的格式(类型),然后把组件包装起来:
// mapStateToProps就是把state映射到ConnectedState(从redux传来的状态)
const mapStateToProps = (state: State, ownProps: OwnProps): ConnectedState => ({
count: state.counter.count
});
// connect根据映射函数,从redux的取数据,然后用一个组件把Counter包起来,把数据传给Counter
// 返回的ConnectedCounter类型是 eact.Component<OwnProps, OwnState>
// 因为ConnectedState已经通过redux和connect拿到了
const ConnectedCounter = connect(mapStateToProps)(Counter);
// 导出ConnectedCounter而不是Counter
export default ConnectedCounter;
就使用来说,你只要知道connect是把redux的状态和action传到组件就可以了。
更进一步,你可以看connect的函数签名(简化版):
type ComponentClass<P> = React.ComponentClass<P>; // ComponentClass就是一个React组件
// ComponentDecorator是个函数,参数类型是ComponentClass<TOriginalProps>,返回值类似是ComponentClass<TOwnProps>
// 就是把原来props为TOriginalProps的component变成props为TOwnProps的组件。
interface ComponentDecorator<TOriginalProps, TOwnProps> {
(component: ComponentClass<TOriginalProps>): ComponentClass<TOwnProps>;
}
// MapStateToProps是个函数,把任意类型的state和TOwnProps组合成TStateProps
interface MapStateToProps<TStateProps, TOwnProps> {
(state: any, ownProps?: TOwnProps): TStateProps;
}
// connect有一个参数mapStateToProps,mapStateToProps可以把state和TOwnProps转成TStateProps,state肯定是connect传过来的。
// connect返回一个ComponentDecorator,ComponentDecorator又把props为TStateProps的组件转回props为TOwnProps的组件(因为TStateProps已经从redux里拿到了,最后还需要自己传的props就是TOwnProps)
function connect<TStateProps, TDispatchProps, TOwnProps>(
mapStateToProps: MapStateToProps<TStateProps, TOwnProps>
): ComponentDecorator<TStateProps, TOwnProps>;
看懂上面的函数签名,不看react-redux
的代码都知道connect
是做什么的。
8 回答4.6k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
6 回答2.3k 阅读
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
1、关于mapStateProps(),注释上说是声明当前组件有关系的state的属性。无论是小型还是大型应用中,state数都是一颗体积庞大的树,会有各种组件的state属性组成,mapStateProps的作用就是只绑定当前组件相关的state属性,这样可以保证避免传入额外的state属性进来。
2、然后我们再看看dispatch,上面state的作用是从组件读取state属性,那么dispatch的作用就是组件告诉action它想要做什么事情,action就找到对应的函数去执行。
比如组件想要改变text的内容,就通过dispatch方法告诉action:喂,action,我不喜欢这句话,赶紧给我换一句显示!!
action收到之后就很听话,马上告诉reducer去更新text,更新text之后,组件就可以接收到新的state属性值了。
3、最后一行代码:App = connect(mapStateToProps, mapDispatchToProps)(App)
上面定义的关联state和action的方法需要绑定到当前组件上面,这句代码的作用就是这个。不指定绑定的组件,万一跑到其他组件去了怎么办呢??
4、我通常不这么写,我的写法是下面这种,意思是一样的
5、so,你喜欢怎么写就怎么写。