导读
你是否苦于在connect
时和select
时得不到提示呢?
又是怎样和page
页面建立连接的呢?
正文
两个简单的Model
LoginModel.ts
export interface LoginModelState {
title: string;
}
const state: LoginModelState = {
title: '今天是劳动节!',
};
export default {
state,
};
UserModel.ts
export interface UserModelState {
name: string;
}
const state: UserModelState = {
name: '小遁',
};
export default {
state,
};
umi会自动识别models
文件夹下的文件,models
可以有多个,可以在不同的位置
在page
目录下建一个ModelStateCollection.ts
文件
import { UserModelState, LoginModelState } from 'umi';
export default interface ModelStateCollection {
LoginModel: LoginModelState;
UserModel: UserModelState;
}
注意这行import { UserModelState, LoginModelState } from 'umi';
,感觉umi
可以做到把它们结合起来
namespace不指定则是文件的名字,需要是唯一的
使用select
就可以得到提示了
LoginModel.ts
import ModelStateCollection from '../ModelStateCollection';
export default {
effects: {
*loadPage({}: LoginModelState, { select }) {
const name = yield select(
({ UserModel }: ModelStateCollection) => UserModel.name,
);
},
},
};
在页面中的使用
不建议使用@connect
,虽然属性已经通过mapStateToProps
给组件了,但外面还是会提示没给到,还有其它tslint错误,而且...,两个字闹心!
Login.tsx
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import ModelStateCollection from '../ModelStateCollection';
interface LoginProps {
title: string;
}
const mapStateToProps = ({ LoginModel }: ModelStateCollection) => ({
title: LoginModel.title,
});
class Login extends PureComponent<LoginProps> {
public render() {
const { title } = this.props;
return <div>{title}</div>;
}
}
export default connect(mapStateToProps)(Login);
结语
除了提示之外,还有约束,毕竟state
要赋初值的,所以这里还是不好省去。
我之前一直觉得title
这种重复的指定很麻烦,于是乎
interface LoginProps extends Partial<LoginModelState> {}
这样很是不好,或许以后TS能发展到很智能,但就目前来看:
-
Login
组件需要什么属性和connect
连接的属性是两回事 - 值和类型定义也是两回事
最好的解决办法是少用 redux
。
宁可写无聊的代码,也不写耍聪明的代码 - React中文文档
网友评论