blog
blog copied to clipboard
如何在 TypeScript 中编写 react-redux 的 connectted 组件
我们使用 react-redux 的 connect 这个 hoc 来实现对组件的状态注入,一般情况下只用到 mapStateToProps
和 mapDispatchToProps
(其实还有不太起眼的 mergeProps
options
这两个可选参数),
connect
方法接受三个范型,分别对应 mapStateToProps
、mapDispatchToProps
、ownProps
的返回值
因此为了对应这里,可以将原组件的 props interface 拆成 这三种类型,再原组件使用的时候使用ts的交叉类型来组合:
const UserInfo: React.FC<StateProps & DispatchProps & OwnProps> = ({}) => {
}
export default connect<StateProps, {logout: Function }, {name: string}>()()
应该遵循这个,不然调用这个组件传入 props 的时候可能会让你觉得 编辑器瞎了。 一个🌰:
import React from 'react';
import { connect } from 'react-redux';
import { Avatar, Menu, Dropdown, Icon } from 'antd';
import './style.less';
import actions from 'components/app/app-actions';
interface StateProps {
userInfo: {
name: string
}
}
interface DispatchProps {
logout: Function
}
const menus = [
{
name: 'PMS', href: '/pms'
}
]
const UserInfo: React.FC<StateProps & DispatchProps> = ({userInfo, logout}) => {
const PmsMenu = (
<Menu>
{
menus
.map((item, key) => <Menu.Item key={key}><a href={item.href}>{item.name}</a></Menu.Item>)
}
<Menu.Item><a onClick={() => logout()}>退出</a></Menu.Item>
</Menu>
)
return <div className="user-info" >
<Dropdown overlay={PmsMenu} trigger={['click']} placement="bottomRight">
<span>
<Avatar size="small" icon="user" />
<span className="nick-name-content">{userInfo.name}</span>
<Icon type="down" />
</span>
</Dropdown>
</div>
}
interface IState {
app: {
userInfo: {
name: string
}
}
}
export default connect<StateProps, {logout: Function }, {name: string}>(
(state: IState) => ({ userInfo: state.app.userInfo }),
(dispatch) => ({logout: () => dispatch(actions.logout())}),
)(UserInfo)