“操作必须是普通对象。使用自定义中间件进行异步操作。”即使应用了 thunk

问题描述 投票:0回答:2

我想弄清楚为什么我会收到“操作必须是普通对象。使用自定义中间件进行异步操作。”当我发送我的 thunk 动作时。根据我的理解,这个问题的正常原因是我的 thunk 中间件没有应用,因此 redux 只需要 POJO 操作,而不是 thunk 操作。但是,除非我弄错了,否则我相信我已经做到了。我还仔细检查以确保我的 thunk 动作创建者实际上返回了 thunk 动作。我环顾四周,甚至询问了 chatgpt,但似乎找不到解决此问题的方法。这是代码:

申请thunk

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import { composeWithDevTools } from 'redux-devtools-extension';

import rootReducer from './services/reducers/root_reducer.js';

// apply logger middleware only in dev env
const composedEnhancer = compose(composeWithDevTools(), applyMiddleware(thunk, logger.default));

const configureStore = (preloadedState = {}) => {
  return createStore(rootReducer, preloadedState, composedEnhancer);
};

export default configureStore;

index.js

import './assets/styles/reset.css';
import './assets/styles/index.css';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { BrowserRouter as Router } from 'react-router-dom';
import configureStore from './store.js';
import App from './app.js';

const rootElement = document.getElementById('root');
const root = ReactDOM.createRoot(rootElement);
root.render(
  <Router>
    <Provider store={configureStore()}>
      <App />
    </Provider>
  </Router>
)

thunk动作

import UserApi from '../api/user_api.js';
import { UserActions } from '../constants/actions.js';
import { displayError } from './error_actions.js';
import userPool from '../../user_pool.js';

export const addUser = (user) => {
  return {
    type: UserActions.addUser,
    payload: user
  };
};

export const register = (registerData) => {
  return async (dispatch) => {
    userPool.signUp(registerData.email, registerData.password, registerData.attributeList, null, (error, result) => {
      if (error) {
        return dispatch(displayError(error));
      } else {
        return dispatch(addUser(result.user));
      }
    });
  }
}

调度thunk行动

  // Called when form is submitted
  const onSubmit = (event) => {
    event.preventDefault();
    const registerParams = {
      email: user.email,
      password: user.password,
      attributeList: []
    };
    delete user.email;
    delete user.password;
    Object.entries(user).forEach(([key, value]) => {
      if (key === "birthdate") {
        const options = { year: 'numeric', month: '2-digit', day: '2-digit' };
        value = value.toLocaleDateString('en-US', options).replace(/\//g, '-');
      }
      let attributeParams = {
        Name: key,
        Value: value
      };
      let cognitoAttribute = new CognitoUserAttribute(attributeParams);
      registerParams.attributeList.push(cognitoAttribute);
    });
    dispatch(register(registerParams));
  };
javascript reactjs redux react-redux redux-thunk
2个回答
0
投票

一个潜在的问题是这条线看起来不对:

const composedEnhancer = compose(composeWithDevTools(), applyMiddleware(thunk, logger.default));

一行有3个问题:

  • applyMiddleware
    应该永远是第一个
  • 如果你要添加devtools设置它应该是最后
  • 但实际上
    composeWithDevtools()
    替换独立的
    compose

所以它真的应该是:

const composedEnhancer = composeWithDevtools(applyMiddleware(thunk, logger.default));

我不确定错误的原因,但很有可能。

HOWEVER,还有一个问题:

你写的 Redux 逻辑风格非常过时。

今天,所有 Redux 用户应该使用我们的官方 Redux Toolkit 包来编写他们的 Redux 代码。它极大地简化了 Redux 的使用,其中包括您示例中的一些代码。

特别是,RTK 的

configureStore
API 使用已配置的 thunk 中间件和 Redux DevTools 设置商店,RTK 的
createAsyncThunk
将为您完成“异步请求的调度操作”工作。

有关如何使用 Redux Toolkit 的详细信息,请参阅我们的文档:


0
投票

...@markerikson 所说的加上...

onSubmit
回调以
dispatch()
的返回值作为参数调用
register()
register()
的返回是一个 Promise,而不是一个可序列化的对象。

register()
dispatch()
的返回值实现(解决)它返回一个 Promise.

© www.soinside.com 2019 - 2024. All rights reserved.