javascript - 在我的 React 应用程序中使用 redux dispatch 获取 TypeScript 错误
问题描述
React 新手,我正在尝试使用 Redux 实现 Flux,但是在使用异步操作调用 dispatch 时遇到 TypeScript 错误。
这是我的 App.tsx :
import React from 'react';
import { IonApp } from '@ionic/react';
import Main from './pages/Main';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './flux/reducers';
import { loginAttempt } from './flux/actions';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
const loggerMiddleware = createLogger();
const store = createStore(rootReducer,
applyMiddleware(
thunkMiddleware, loggerMiddleware
)
);
let promise = store.dispatch(loginAttempt('test@host.org','test'));
promise.then(() => console.log(store.getState()));
class App extends React.Component {
render() {
return (
<Provider store={store}>
<IonApp>
<Main/>
</IonApp>
</Provider>
)}
}
export default App;
我的行动:
import fetch from 'cross-fetch';
import { Dispatch, Action } from 'redux';
export const LOGIN_REQUEST = 'LOGIN_REQUEST';
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export function loginRequest() {
return { type: LOGIN_REQUEST }
}
export function loginFailure(error: string) {
return { type: LOGIN_FAILURE, error }
}
export function loginSuccess(sessionId: string) {
return { type: LOGIN_SUCCESS, sessionId }
}
export async function loginAttempt(email: string, password: string) {
return async function (dispatch: Dispatch<Action<any>>) {
dispatch(loginRequest());
return fetch("http://127.0.0.1:5000/login", {
method: "post",
headers: new Headers({
"Content-Type": "application/json",
Accept: "application/json",
}),
body: JSON.stringify({email, password})
})
.then(
response => response.json()
)
.then(json =>
dispatch(loginSuccess(json))
)
}
}
和减速器:
import { LOGIN_REQUEST, LOGIN_FAILURE, LOGIN_SUCCESS } from './actions';
import { combineReducers } from 'redux';
const initialState = {connected: false, sessionId: "", isFetching: false, failed: false, error:""};
function login(state = initialState, action: any) {
switch (action.type) {
case LOGIN_REQUEST:
return Object.assign({}, state, {
isFetching: true
});
case LOGIN_FAILURE:
return Object.assign({}, state, {
isFetching: false,
failed: true,
error: action.error
});
case LOGIN_SUCCESS:
return Object.assign({}, state, {
connected: true,
isFetching: false,
sessionId: action.sessionId
});
default:
return state
}
}
const rootReducer = combineReducers({
login
})
export default rootReducer;
这会在编译时产生 TypeScript 错误:
Argument of type 'Promise<(dispatch: Dispatch<Action<any>>) => Promise<{ type: string; sessionId: string; }>>' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type 'Promise<(dispatch: Dispatch<Action<any>>) => Promise<{ type: string; sessionId: string; }>>' but required in type 'AnyAction'. TS2345
我敢肯定这是我的一些愚蠢行为,但我找不到我应该更改哪种类型才能使其正常工作。
知道我做错了什么吗?
解决方案
一位朋友最终帮我修复了它,我需要将中间件转换为 ThunkMiddleware :
const store = createStore(
rootReducer,
applyMiddleware(
thunkMiddleware as ThunkMiddleware<typeof initialState, Action<any>>
)
);
从我的减速器导入的初始状态。
我的 loginAttempt 函数也已更改为不直接返回承诺:
export function loginAttempt(email: string, password: string) {
return async function (dispatch: any) {
[...]
}
}
推荐阅读
- css - 如何制作取决于目标元素包含的 html 标签/文本节点的 CSS 选择器
- swift - 获取 Button 和 Textfield 数据,当它们在 swift 5 中以编程方式添加时
- php - 使用 Docker 和 php7.4 配置 memcached
- bokehjs - 测量散景中直方图之间的距离
- c - 如何在 centos8 中使用“dnf install”安装文件 libc.a
- javascript - 如何在 Next.JS 中使用 URL 查询创建条件逻辑?
- python - 如何在 Python 3 中执行 input() 方法时输入换行符?
- rust - 由于对 `.into_iter()` 的隐式调用,移动了对向量的可变引用,但显式调用 `.into_iter()` 有效
- python - 使用 Telebot ValueError 编写电报机器人时出错:check_hostname 需要 server_hostname
- javascript - 在javascript中每2秒更改一次url