希望一些Typescript专家可以帮助我,因为我是新手。
我正在尝试使用react-redux将组件状态存储到redux中,我遇到的一个问题是我需要一种组织可重用组件的方法,以使它们在全局存储中的状态不会相互干扰。
我受到https://github.com/eloytoro/react-redux-uuid的启发,该提议建议使用安装时随机生成的UUID将组件的状态自动注册到全局存储中,将状态存储在该“切片”中,并在卸载时将其从redux中删除。连接时,它将在mapStatetoProps中向组件显示组件状态数据的“切片”。但是,该库已失效且不符合Typescript。
我已经修改了代码,因此使用起来很容易:
import { connectUUID,IRedux_UUID_DispatchProps } from 'lib/Redux_UUID';
export type TAdminUserListReduxState = {
loadStatus:string,
user_list:{user_list:any[]},
loadErrorDesc:string
}
export interface AdminUserListProps {
company_id:number,
userClickPath:string
}
export const AdminUserListContainer:FunctionComponent<AdminUserListProps & TAdminUserListReduxState & IRedux_UUID_DispatchProps> = (props) => {
...
props.dispatchUUID({
type: 'SOME_ACTION',
payload: {
action_param1: param1;
}
});
...
};
const mapStateToProps = (state:{localState:TAdminUserListReduxState,globalState:any}) => {
return state.localState;
};
export default connectUUID('AdminUserListContainer',mapStateToProps)(AdminUserListContainer);
我基本上使用我自己的connectUUID()覆盖react-redux中的connect(),这将实现HOC,该HOC进行UUID注册/取消注册+切片特定于组件的状态以传递到mapStateToProps中的props中(这个想法是来自react-redux-uuid库)。为简化起见,我不使用动作创建者,所以不使用分派映射,而是使用dispatchUUID({action})直接分派动作(此分派会将UUID注入到动作中,以便减速器知道要减少哪个“切片”) )。
完整代码位于:https://github.com/andrwo/react-redux-connectUUID/blob/master/Redux_UUID.tsx
所有这些都很好用。当我的React应用运行时,它将本地组件状态注册到uuid redux部分(并在该组件卸载时将其删除):
我现在的问题是,在我的connectUUID()HOC实现中,我在一些声明中使用了 any ,因此这删除了我的组件类型检查,如果您使用react-redux中的connect()HOC:
export const connectUUID = (name:string, mapStateToProps?:any) => <T extends Matching<{}, T>>(Component:React.ComponentType<T>) => {
const ConnectedComponent = connect(
(mapStateToProps?wrapMapStateToProps(mapStateToProps, name):null)
)(Component);
class ConnectUUID extends React.Component<any> {
uuid:string='';
dispatchUUID = (action:any) => {
const action2={
...action,
meta: Object.assign(
{},
action.meta,
name && {[NAME_KEY]: name},
this.uuid && {[UUID_KEY]: this.uuid},
)
}
this.props.dispatch(action2);
}
componentWillMount() {
this.uuid = this.props.uuid || createUUID();
if (!this.props.uuid) {
this.props.dispatch({
type: REGISTER,
meta: {
[UUID_KEY]: this.uuid,
[NAME_KEY]: name
}
});
}
}
componentWillUnmount() {
if (!this.props.uuid) {
this.props.dispatch({
type: UNREGISTER,
meta: {
[UUID_KEY]: this.uuid,
[NAME_KEY]: name
}
});
}}
render() {
return (
<ConnectedComponent
{...this.props}
dispatchUUID={this.dispatchUUID}
uuid={this.uuid}
/>
);
}
}
return connect()(ConnectUUID);
};
所以现在当我使用此组件时,它可以工作,因为我使用React.Component(any)消除了类型错误,我还在mapStateToProps中使用了(any)...但是...我丢失了该组件VS代码中的prop类型检查(以下代码会触发TS错误,因为invalidProp无效,因此仅允许props(userClickPaths,company_id,uuid?):
import AdminUserListContainer from 'component/svc/AdminUserListContainer';
...
(props) => return (
...
<AdminUserListContainer
userClickPaths={`${parentPath}/AdminUser`}
company_id={company_id}
invalidProp={'blahBlah'} // this prop should be invalid
/>
我试图查看react-redux的类型以了解它们的工作方式,但是所有的InferableProps等都让它感到困惑。这看起来非常密集!
任何大师都可以向我指出正确的方向,我该如何进行connectUUID()函数的键入,以便正确进行键入?预先感谢!