Я пытаюсь заставить Redux-Thunk работать в приложении TypeScript React. К сожалению, я столкнулся с этой ошибкой и исчерпал все ресурсы, которые мог найти, пытаясь найти ответ на эту ошибку.
Я искренне застрял и надеюсь, что кто-то может помочь.
Ошибка :
Argument of type 'typeof App' is not assignable to parameter of type 'ComponentType<Matching<{ todos: TodoItem[]; loading: boolean; } & typeof import("C:/Users/cevan/Documents/reactFinalShow/frontend-app/src/store/actions"), ClassAttributes<App> & IAppProps & DispatchProps>>'.
Type 'typeof App' is not assignable to type 'ComponentClass<Matching<{ todos: TodoItem[]; loading: boolean; } & typeof import("C:/Users/cevan/Documents/reactFinalShow/frontend-app/src/store/actions"), ClassAttributes<App> & IAppProps & DispatchProps>, any>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'Matching<{ todos: TodoItem[]; loading: boolean; } & typeof import("C:/Users/cevan/Documents/reactFinalShow/frontend-app/src/store/actions"), ClassAttributes<App> & IAppProps & DispatchProps>' is not assignable to type 'Readonly<Props>'.
The types returned by 'getTodoItems()' are incompatible between these types.
Type '(dispatch: Dispatch<AnyAction>) => Promise<string | void | TodoItem[]>' is missing the following properties from type 'TodoItem[]': pop, push, concat, join, and 27
more. TS2345
Мой код
App.tsx
import React, { Component } from 'react'
import { connect } from 'react-redux';
import * as TodoItemActions from './store/actions'
import { RootState } from './store';
import { ThunkDispatch } from 'redux-thunk';
import { AnyAction, Dispatch, bindActionCreators } from 'redux';
import { GotTodoItems } from './store/types';
import { TodoItem } from './models/TodoItem';
export interface IAppProps {
todos: TodoItem[];
loading: boolean;
}
type Props = IAppProps & DispatchProps;
export class App extends React.Component<Props> {
public render() {
let { getTodoItems } = this.props;
let idk = getTodoItems();
console.log(idk);
return (
<div>
</div>
);
}
}
const mapStateToProps = (state: RootState) => {
console.log(state);
return {
todos: state.todoReducer.todoItems,
loading: state.todoReducer.loading
};
}
const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators(TodoItemActions, dispatch);
interface DispatchProps {
getTodoItems: () => TodoItem[];
}
export default connect(
mapStateToProps, //bring in the mapStateToProps function to inform redux of what you want to bring in and how to bring it in (to props)
mapDispatchToProps
//bring in specific actions into this component
)(App);
actions.ts (из моего магазина)
import { TodoActionTypes, GETTING_TODO_ITEMS, GOT_TODO_ITEMS } from "./types";
import { TodoItem } from "../models/TodoItem";
import agent from "../api/agent";
import { Dispatch } from 'redux';
import { AppActions } from "../models/actions";
import { store } from '../index';
const requestTodoItems = (): AppActions => {
return {
type: GETTING_TODO_ITEMS,
todoItems: []
}
}
export function getTodoItems() {
return (dispatch: Dispatch) => {
dispatch(requestTodoItems());
let errorEncountered = false;
let hasErrored = false;
let response = agent.ToDoApis.getList(new URLSearchParams);
return response.then(
value => {
//success
console.log(value)
return value;
},
reason => {
//rejection
console.log(reason)
}
).catch(error => `Error when fetching to do items ${error}`)
}
}
// agent.ToDoApis.getList
// .(
// (response) => response.json(),
// (error) => {
// hasErrored = true;
// console.log(error);
// dispatch(requestTodoItems());
// }
// )
// .then((json) => {
// if (!hasErrored) {
// dispatch(returnTodoItems(json));
// }
// });
// return agent.ToDoApis.getList(new URLSearchParams)
// .then(
// (response) => response.IsDone,
// (error) => {
// errorEncountered = true;
// console.log(error);
// dispatch(requestTodoItems());
// }
// )
// .then((json) => {
// if(!errorEncountered){
// dispatch(returnTodoItems(json))
// }
// })
// export async function getTodoItems(isDone: boolean): Promise<TodoActionTypes> {
// console.log("ABOVE");
// const response = await agent.ToDoApis.getList;
// console.log("ABOVE");
// console.log(response);
// console.log("ABOVE");
// dispatch({
// type: GET_TODO_ITEMS,
// isDone: isDone
// });
// }
// export function createNewTodo(todoItem: TodoItem): TodoActionTypes {
// return {
// type: CREATE_NEW_TODO,
// todoItem: todoItem
// }
// }
// export function toggleDoneStatusForTodo(id: string): TodoActionTypes {
// return {
// type: TOGGLE_DONE_STATUS_FOR_TODO,
// id: id
// }
// }
// export function updateEntireTodo(todoItem: TodoItem): TodoActionTypes {
// return {
// type: UPDATE_ENTIRE_TODO,
// todoItem: todoItem
// }
// }
// export function deleteTodo(id: string): TodoActionTypes {
// return {
// type: DELETE_TODO,
// id: id
// }
```
index.tsx (where I configure the store)
```
import { combineReducers, createStore, applyMiddleware } from "redux"
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk, { ThunkMiddleware } from 'redux-thunk'; //NEW LINE
import { todoReducer } from "./reducers";
import { TodosState } from "./types";
import { AppActions } from "../models/actions";
const rootReducer = combineReducers({
todoReducer: todoReducer
})
export type RootState = ReturnType<typeof rootReducer>;
export default function configureStore() {
const store = createStore(
rootReducer,
composeWithDevTools(
applyMiddleware(
thunk as ThunkMiddleware<TodosState, AppActions>
) //NEW FOR THUNK.
)
);
// thunk as ThunkMiddleware<RootState, AppActions>
return store;
}
```
reducers.ts (My reducer)
```import { TodosState, TodoActionTypes, GETTING_TODO_ITEMS, GOT_TODO_ITEMS } from "./types";
const initialState: TodosState = {
todoItems: [],
loading: false
};
export function todoReducer(state = initialState, action: TodoActionTypes): TodosState {
switch (action.type) {
case GETTING_TODO_ITEMS:
return {
...state,
loading: true
}
case GOT_TODO_ITEMS:
return {
...state,
todoItems: action.todoItems,
loading: true
}
default:
return state;
}
}
```
types.ts (my types file for redux)
```
import { TodoItem } from "../models/TodoItem";
import { Action } from "redux";
export interface TodosState {
todoItems: TodoItem[];
loading: boolean;
}
//Action Type Definitions.
//GET (AKA GET)
export const GETTING_TODO_ITEMS = "GETTING_TODO_ITEMS";
export const GOT_TODO_ITEMS = "GOT_TODO_ITEMS";
//CREATE (AKA POST)
export const CREATING_NEW_TODO = "CREATING_NEW_TODO";
export const CREATED_NEW_TODO = "CREATED_NEW_TODO";
//TOGGLE (AKA PATCH)
export const TOGGLING_DONE_STATUS_FOR_TODO = "TOGGLING_DONE_STATUS_FOR_TODO";
export const TOGGLED_DONE_STATUS_FOR_TODO = "TOGGLED_DONE_STATUS_FOR_TODO";
//UPDATE ENTIRE TODO (AKA PUT)
export const UPDATING_ENTIRE_TODO = "UPDATING_ENTIRE_TODO";
export const UPDATED_ENTIRE_TODO = "UPDATED_ENTIRE_TODO";
//DELETE TODO (AKA DELETE)
export const DELETING_TODO = "DELETING_TODO";
export const DELETED_TODO = "DELETED_TODO";
//Actions. (NOTE ASYNC ACTIONS WITH REDUX THUNK ARE VERY DIFFERENTLY WRITTEN!!!)
//WARNING: Very different from redux actions from before for Async!!!
export interface GettingTodoItems extends Action<typeof GETTING_TODO_ITEMS> {
todoItems: TodoItem[];
}
export interface GotTodoItems extends Action<typeof GOT_TODO_ITEMS> {
todoItems: TodoItem[];
}
export interface CreatingNewTodo extends Action<typeof CREATING_NEW_TODO> {
}
export interface CreatedNewTodo extends Action<typeof CREATED_NEW_TODO> {
}
export interface TogglingDoneStatusForTodo extends Action<typeof TOGGLING_DONE_STATUS_FOR_TODO> {
}
export interface ToggledDoneStatusForTodo extends Action<typeof TOGGLED_DONE_STATUS_FOR_TODO> {
}
export interface UpdatingEntireTodo extends Action<typeof UPDATING_ENTIRE_TODO> {
}
export interface UpdatedEntireTodo extends Action<typeof UPDATED_ENTIRE_TODO> {
}
export interface DeletingTodo extends Action<typeof DELETING_TODO> {
}
export interface DeletedTodo extends Action<typeof DELETED_TODO> {
}
export type TodoActionTypes =
GettingTodoItems | GotTodoItems |
CreatingNewTodo | CreatedNewTodo |
TogglingDoneStatusForTodo | ToggledDoneStatusForTodo |
UpdatingEntireTodo | UpdatedEntireTodo |
DeletingTodo | DeletedTodo;
//Examples of what doesn't work HERE!
// interface CreatingNewTodo {
// type: typeof CREATE_NEW_TODO;
// todoItem: TodoItem;
// }
// interface TogglingDoneStatusForTodo {
// type: typeof TOGGLE_DONE_STATUS_FOR_TODO;
// id: string;
// }
// interface UpdatingEntireTodo {
// type: typeof UPDATE_ENTIRE_TODO;
// todoItem: TodoItem;
// }
// interface DeletingTodo {
// type: typeof DELETE_TODO;
// id: string;
// }
```