[英]Error in Types for the reducers in TypeScript in React-Redux
我正在为我的React-Redux应用程序使用TypeScript。 我遵循TypeScript React Starter ,但是,上面提到的示例没有任何带有某些参数/有效载荷的操作方法。
我有一个简单的要求-
显示名称列表,并在单击按钮时添加新名称。 单击另一个按钮时,将添加2个名称。
应用index.tsx
的入口点看起来像这样-
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './index.css';
import { createStore } from 'redux';
import { StoreState } from './types';
import { listUsers } from './reducers';
import { Provider } from 'react-redux';
import ListUsers from './containers/ListUsers';
const store = createStore<StoreState>(listUsers, {
'users': [
{
'id': 0,
'firstName': 'Aniyah',
'lastName': 'Luettgen',
'phone': '861-332-5113',
'email': 'Danika.Ryan84@yahoo.com',
'role': 'admin'
},
{
'id': 1,
'firstName': 'Alisa',
'lastName': 'Pacocha',
'phone': '085-056-3901',
'email': 'Eusebio68@yahoo.com',
'role': 'admin'
}
]
});
ReactDOM.render(
<Provider store={store}>
<ListUsers/>
</Provider>,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();
常量文件( constants/index.tsx
)看起来像这样-
export const LIST_USERS = 'LIST_USERS';
export type LIST_USERS = typeof LIST_USERS;
export const ADD_USER = 'ADD_USER';
export type ADD_USER = typeof ADD_USER;
export const ADD_USERS = 'ADD_USERS';
export type ADD_USERS = typeof ADD_USERS;
类型( types/index.tsx
)是-
export interface User {
id: number;
firstName: string;
lastName: string;
phone: string;
email: string;
role: string;
}
export interface StoreState {
users: Array<User>;
}
export interface Action<T> {
type: string;
payload?: T;
}
我的组件( components/ListUsers.tsx
)看起来像这样-
import * as React from 'react';
import { DispatchProps, ListUsersProps } from '../containers/ListUsers';
import { User } from '../types';
interface ListState {
counter: number;
}
class ListUsers extends React.Component<ListUsersProps & DispatchProps, ListState> {
constructor(props: ListUsersProps & DispatchProps) {
super(props);
this.addUser = this.addUser.bind(this);
this.addMultipleUser = this.addMultipleUser.bind(this);
this.state = {
counter: 0
};
}
render() {
return (
<div>
<button onClick={() => this.addUser()}>Add User</button>
<button onClick={() => this.addMultipleUser()}>Add User</button>
{this.props.users.map((user: User) => (
<div key={user.id}>{user.firstName}</div>
))}
</div>
);
}
private addUser() {
this.props.addUser({
id: this.state.counter,
firstName: 'abcd',
lastName: 'efgh',
email: 'abcd@gmail.com',
phone: '1234567890',
role: 'admin'
});
this.setState({
...this.state,
counter: this.state.counter + 1
});
}
private addMultipleUser() {
this.props.addUsers([{
id: this.state.counter,
firstName: 'abcd',
lastName: 'efgh',
email: 'abcd@gmail.com',
phone: '1234567890',
role: 'admin'
}, {
id: this.state.counter,
firstName: 'ijkl',
lastName: 'mnop',
email: 'ijkl@gmail.com',
phone: '1234567890',
role: 'admin'
}]);
this.setState({
...this.state,
counter: this.state.counter + 2
});
}
}
export default ListUsers;
我的容器组件( containers/ListUsers.tsx
)看起来像这样-
import { connect, Dispatch } from 'react-redux';
import { Action, StoreState, User } from '../types';
import ListUsers from '../components/ListUsers';
import { addUser, addUsers } from '../actions';
export interface ListUsersProps {
users: Array<User>;
}
export interface DispatchProps {
addUser(user: User): Action<User>;
addUsers(users: Array<User>): Action<Array<User>>;
}
export const mapStateToProps = (state: StoreState): ListUsersProps => {
return {
users: state.users
};
};
export const mapDispatchToProps = (dispatch: Dispatch<DispatchProps>) => {
return {
addUser: (user: User) => dispatch(addUser(user)),
addUsers: (users: Array<User>) => dispatch(addUsers(users))
};
};
export default connect<ListUsersProps, DispatchProps, {}>(mapStateToProps, mapDispatchToProps)(ListUsers);
现在这是我面临问题的reducers/index.tsx
( reducers/index.tsx
)-
import { Action, StoreState, User } from '../types';
import { ADD_USER, ADD_USERS, LIST_USERS } from '../constants';
export const listUsers = (state: StoreState, action: Action<User>): StoreState => {
switch (action.type) {
case LIST_USERS:
return state;
case ADD_USER:
return {
...state,
users: action.payload === undefined ? [...state.users] : [...state.users, action.payload]
};
case ADD_USERS:
return {
...state,
users: action.payload === undefined ? [...state.users] : [...state.users, ...action.payload]
};
default:
return state;
}
};
这里的编译器说在reducers/index.tsx
中
case ADD_USERS:
return {
...state,
users: action.payload === undefined ? [...state.users] : [...state.users, ...action.payload]
};
该action.payload
是User
而不是Array<User>
,这是正确的(我已将reducer声明为类型(state: StoreState, action: Action<User>)
)。
我该如何处理? 如果没有其他选择,我将不得不为每个具有不同payload
ACTION
编写单独的reducer,我认为这是不好的。
我使用DispatchProps
类型的方式在我看来也很奇怪。 我试图按照此为各类mapStateToProps
和mapDispatchToProps
。
有什么解决办法吗?
PS:我正在使用react
, redux
和react-redux
库。
我找到了解决方案。 我不确定这样做是否正确。
与其像这样使动作类型通用,不如说是-
interface Action<T> {
type: string;
payload?: T;
}
我为每个Action
创建了一个单独的动作类型 ,然后减速器接受的动作类型将为|
其中。
因此,类型看起来像这样( types/index.tsx
)-
import { ADD_USER, ADD_USERS, LIST_USERS } from '../constants';
export interface User {
id: number;
firstName: string;
lastName: string;
phone: string;
email: string;
role: string;
}
export interface StoreState {
users: Array<User>;
}
export type ListUsersAction = {type: typeof LIST_USERS};
export type AddUserAction = {type: typeof ADD_USER, payload: User};
export type AddUsersAction = {type: typeof ADD_USERS, payload: Array<User>};
export type Actions = ListUsersAction | AddUserAction | AddUsersAction;
容器组件( containers/ListUsers.tsx
)看起来像这样-
import { connect, Dispatch } from 'react-redux';
import { AddUserAction, AddUsersAction, StoreState, User } from '../types';
import ListUsers from '../components/ListUsers';
import { addUser, addUsers } from '../actions';
export interface ListUsersProps {
users: Array<User>;
}
export interface DispatchProps {
addUser(user: User): AddUserAction;
addUsers(users: Array<User>): AddUsersAction;
}
export const mapStateToProps = (state: StoreState): ListUsersProps => {
return {
users: state.users
};
};
export const mapDispatchToProps = (dispatch: Dispatch<DispatchProps>) => {
return {
addUser: (user: User) => dispatch(addUser(user)),
addUsers: (users: Array<User>) => dispatch(addUsers(users))
};
};
export default connect<ListUsersProps, DispatchProps>(mapStateToProps, mapDispatchToProps)(ListUsers);
不再有编译错误,并且已正确接收ADD_USER
和ADD_USERS
payload
。
还有就是要减少操作类型样板推荐这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.