我有一个简单的应用程序,它在第一次加载时分派一个操作来填充商店。我希望能够在then上运行dispatch方法,但是类型记录会对此抱怨。
(根据redux的文档,发送操作的返回值是动作本身的返回值)
码箱中可用的代码
// app.jsx
function App() {
const dispatch = useAppDispatch();
useEffect(() => {
dispatch(getTodos()).then((todos) => console.log(todos));
// ^^^^^
// Property 'then' does not exist on type '{ type: "GET_TODOS"; payload: Promise<AxiosResponse<Todo[], any>>; }'.
}, []);
return <div className="App">Hello World!</div>;
}存储配置
我使用@reduxjs/toolkit配置我的存储,并为此设置了一个redux-promise-middleware,以便在“实现”基于承诺的操作时,<ACTION>_FULFILLED操作也将被分派。
// store.ts
import { configureStore } from '@reduxjs/toolkit';
import promiseMiddleware from 'redux-promise-middleware';
import rootReducer from './reducer';
import { useDispatch } from 'react-redux';
const store = configureStore({
reducer: rootReducer,
middleware: [promiseMiddleware],
});
export type RootState = ReturnType<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export default store;减速器
// reducer.ts
import produce, { Draft } from "immer";
import { Action } from "./action";
export type Todo = {
userId: number;
id: number;
title: string;
completed: boolean;
}
interface State {
todos: Todo[];
}
const initialState: State = {
todos: []
};
const reducer = produce((draft: Draft<State>, action: Action) => {
switch (action.type) {
case "GET_TODOS_FULFILLED": {
const todos = action.payload.data;
return todos;
}
}
}, initialState);
export default reducer;动作
// action.ts
import axios from "axios";
import type { AxiosResponse } from "axios";
import type { Todo } from './reducer'
export const getTodos = (): {
type: "GET_TODOS";
payload: Promise<AxiosResponse<Todo[]>>;
} => ({
type: "GET_TODOS",
payload: axios.get("https://jsonplaceholder.typicode.com/todos")
});
export type Action = ReturnType<typeof getTodos>;发布于 2022-04-07 13:37:10
好吧,我自己想出来的。问题是useAppDispatch的类型不正确。
所以在store.ts中,而不是
export const useAppDispatch = () => useDispatch<AppDispatch>();我们应该
import type { ThunkAction, ThunkDispatch } from "redux-thunk";
export type AppThunk<RT = void> = ThunkAction<
Promise<RT>,
RootState,
unknown,
AnyAction
>;
export type AppThunkDispatch = ThunkDispatch<RootState, void, Action>;
export const useAppDispatch = () => useDispatch<AppThunkDispatch>();然后在action.ts中,我们可以编写这样的thunk操作:
export const getTodos =
(): AppThunk<{ type: "SET_TODOS"; payload: Todo[] }> => (dispatch) =>
axios
.get<Todo[]>("https://jsonplaceholder.typicode.com/todos")
.then((response) => response.data)
.then((todos) => dispatch(setTodos(todos)));
export const setTodos = (
todos: Todo[]
): {
type: "SET_TODOS";
payload: Todo[];
} => ({
type: "SET_TODOS",
payload: todos
});最后,对于在我们的应用程序中的任何地方使用调度:
dispatch(getTodos()).then((todos) => console.log(todos));发布于 2022-04-06 13:33:54
您可以创建一个承诺,然后可以像这样使用.then。
import { useEffect } from "react";
import { getTodos } from "./action";
import { useAppDispatch } from "./store";
function App() {
const dispatch = useAppDispatch();
const myPromise = ()=>Promise.resolve(dispatch(getTodos())); /// creating promise
useEffect(() => {
myPromise().then((res:any)=>{
console.log(res.value.data)
})
}, []);
return <div className="App">Hello World!</div>;
}
export default App;希望你长得像这样。
发布于 2022-04-06 13:46:57
dispatch将返回您的操作(thunk)返回的任何内容。
似乎这部分
({
type: "GET_TODOS",
payload: axios.get("https://jsonplaceholder.typicode.com/todos")
})可能是错的:你想要的可能是
const getTodos = (): ThunkAction => (dispatch) =>
axios.get("https://jsonplaceholder.typicode.com/todos").then(todos => {
dispatch({type: "GET_TODOS", payload: todos});
return todos;
});这样,你们两个的行动就会被触发,你们的承诺也会从待定任务的有效载荷中恢复过来。
您还可以根据ThunkAction的情况使用泛型键入https://redux.js.org/usage/usage-with-typescript#type-checking-redux-thunks。
https://stackoverflow.com/questions/71766161
复制相似问题