问题引入
dva一般用connect进行model数据与组件绑定。通过例子来看具体的绑定方式。具体的流程如下:
- 组件里面有一个按钮,点击按钮进入model层的effect方法
- model中的effect执行完毕后,调用reducer刷新model中state值,同时也刷新组件的显示效果
在这个结构里,有一个问题就是组件中显示的值为model中的state,那么这就需要将组件中的数据与model中的state作绑定。
现在有一个组件:
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| interface MyProps{ dispatch:Dispatch num:number } interface MyState { num:number iconLoading:boolean } class OtherComponent extends Component<MyProps, MyState> { state = { num:12, iconLoading:false }; enterIconLoading = () => { const {dispatch}=this.props; this.setState({ iconLoading: true }); const {num} = this.props dispatch({ type: "otherModel/fetchNum", payload2: { numCount:num, } }) this.setState({iconLoading:false}) }; render() { const {num} = this.props return ( <div> <Button type="primary" icon="poweroff" loading={this.state.iconLoading} onClick={this.enterIconLoading}> {num} </Button> </div> ) } } export default OtherComponent;
|
model层中代码:
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| export interface StateType { num: number iconLoading: boolean }
export interface ModelType { namespace: string; state: StateType; effects: {}; reducers: {}; } const Model: ModelType = { namespace: 'otherModel', state: {num: 1873, iconLoading: false}, reducers: { addNum(state: StateType, {payload: {num}}:{payload:{num:number}}) { return {...state, num} } }, effects: { * fetchNum({payload2}: { payload2: AnyAction }, {call,put }: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T }) { console.log(payload2) yield put({ type: "addNum", payload: { num: payload2.numCount + 1, }, }) } },
}
export default Model;
|
现在可以看到两边的逻辑都已经写好了,看看如何绑定model中的num值。
方法一
传统方式,使用connect,在组件中写入。这样写之后,就会在组件的props中生成一个otherModel的属性。
使用的时候用const {otherModel}=this.props
即可取到。这里的otherModel
为model 的命名空间。
jsx1 2 3 4 5 6 7
| function mapStateToProps (model) { const { otherModel} = model return { otherModel, } } export default connect(mapStateToProps)(OtherComponent);
|
如果想使用model state中的某几个属性,那么使用,如下:
jsx1 2 3 4 5 6
| function mapStateToProps (model) { const { num} = model.otherModel return { num, } }
|
方法二
现在一般都用@connect装饰器的模式。这种模式看起来更简单一些,但是初次使用,语法上还是需要看一下的:
jsx1
| @connect(({otherModel}:{otherModel:StateType})=>({otherModel}))
|
在这里需要注意,这样引入的话,类似于上面的全部引入。但是如果想要部分引入属性。需要用下面的方法:
jsx1
| @connect(({otherModel}:{otherModel:StateType})=>({num:otherModel.num}))
|
即传入的参数永远为otherModel,也就是这个唯一的命名空间