[英]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.