当前位置: 首页 > 知识库问答 >
问题:

与Redux thunk异步/等待。获取错误:操作必须是普通对象。使用自定义中间件进行异步操作

楚嘉胜
2023-03-14

我正在尝试将async await与redux thunk中间件一起使用,但我得到了红屏,错误操作必须是普通对象。使用自定义中间件进行异步操作。我想我没有返回正确类型的值。我按下按钮将twitter用户链接到现有的firebase帐户。该按钮到达一个名为toggleTwitterAuthState的函数:

export const toggleTwitterAuthState =  (twitterIsCurrentlyLinked, contributorUserId) => {

  let actionName = "";


    if (twitterIsCurrentlyLinked) {
      console.log("Unlinking twitter");
      actionName = "TWITTER_UNLINK";
       unlinkTwitterAccount(contributorUserId);
    } else {
      console.log("Linking twitter");
      linkTwitterAccount(contributorUserId);
      actionName = "TWITTER_LINK";
    }



};

它调用函数link Twitter帐户,我使用的反应本地调试器把一个断点返回异步(调度)和它到达那里,但里面的代码从来没有得到执行,我得到的红色屏幕与上面描述的错误

linkTwitterAccount =  (contributorUserId) => {

       return async (dispatch)=>{

        console.log("about to link twitter user");
        RNTwitterSignIn.init(config.twitter.consumer_key, config.twitter.consumer_secret);
        dispatch(authOperationBegan());

        let linkToTwitterResult;
        let twitterTokensObject;
        let loginData;
        //get credentials

        try {
          loginData = await RNTwitterSignIn.logIn();
          console.log("Twitter login data", loginData);
        } catch (err) {
          console.log("Error with twitter login result", error);
          dispatch(authOperationFailed(err));
        }

        //link to react native firebase

        try {

          const {
            authToken,
            authTokenSecret
          } = loginData;
          const user = firebase.auth().currentUser;
          // create a new firebase credential with the token
          const twitterCredential = firebase.auth.TwitterAuthProvider.credential(authToken, authTokenSecret);
          console.log(twitterCredential);

          // link to this account with credential
          const linkingResult = await user.linkAndRetrieveDataWithCredential(twitterCredential);
          console.log("Success Linking twitter", linkingResult);

          var currentUser = linkingResult.user;

          var displayName;
          var photoUrl;
          var email;
          var phoneNumber;
          var twitterUserId;

          currentUser.providerData.map(elem => {
            if (elem.providerId == "twitter.com") {

              displayName = elem.displayName;
              photoUrl = elem.photoURL;
              email = elem.email;
              phoneNumber = elem.phoneNumber;
              twitterUserId = elem.uid;

            }
          });


          twitterTokensObject = {
            "contributor_user_id": contributorUserId,
            "twitter_id": twitterUserId,
            "twitter_access_token": authToken,
            "twitter_access_token_secret": authTokenSecret,
            "display_name": displayName,
            "photo_url": photoUrl,
            "phone_number": phoneNumber,
            "email": email
          };


        } catch (err) {
          alert("Error linking asociando cuenta: " + err);
          dispatch(authOperationFailed(err));
        }

        //TODO: upsert twitter user data to DB

        dispatch(authOperationFinished());
       }
      }

我的redux thunk配置是这样的,我从一个udemy课程中学到的,在这个课程中,这个人使用了一个组件函数https://www.udemy.com/react-native-the-practical-guide/:

import { createStore, combineReducers, compose, applyMiddleware } from 'redux';
import thunk from "redux-thunk";

import foundationsReducer from './reducers/foundations';
import sponsorsReducer from './reducers/sponsors';
import authReducer from './reducers/auth';

const rootReducer = combineReducers({
    foundations: foundationsReducer,
    sponsors: sponsorsReducer,
    auth:authReducer
});

let composeEnhancers = compose;

if (__DEV__) {
    composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
}

const configureStore = () => {
    return createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)));
};

export default configureStore;

我在索引上使用这个redux-thunk配置。js:

import React from 'react';
import { AppRegistry } from 'react-native';
import { Provider } from 'react-redux';
import App from './App';
import configureStore from './src/store/configureStore';

const store = configureStore();

const RNRedux = () => (
    <Provider store={store}>
        <App />
    </Provider>
);

AppRegistry.registerComponent('rnfundkers', () => RNRedux);

只是想让您知道,redux thunk正在为其他操作工作,但是这个异步等待案例在某种程度上是不同的,我无法看到。你知道会出什么问题吗?如果我去掉包装器和分派,函数本身就会工作,它会做它必须做的事情,但是因为我需要这些分派来更新微调器,所以这个问题就出现了。谢谢

编辑:以下是操作:

export const authOperationBegan =  () => {
  return {
    type: AUTH_OPERATION_BEGAN
  };
}

export const authOperationFinished =  () => {
  return {
    type: AUTH_OPERATION_FINISHED
  };
}

export const authOperationFailed =  (err) => {
  return {
    type: AUTH_OPERATION_FAILED,
    error: err
  };
}

我还有其他功能可以分派相同的3个动作,它们工作得很好,例如:

export const tryAuth = (authData, authMode) => {
  return dispatch => {
    dispatch(authOperationBegan());

    const email = authData.email,
      password = authData.password;

    if (authMode === "signup") {

      firebase.auth().createUserWithEmailAndPassword(email, password)
        .then((user) => {


          // TODO: upsert user to our db
          dispatch(authOperationFinished());

        })
        .catch((error) => {
          const {
            code,
            message
          } = error;

          dispatch(authOperationFailed(err));

        });

    } else if (authMode == "login") {

      firebase.auth().signInAndRetrieveDataWithEmailAndPassword(email, password)
        .then((data) => {

          dispatch(authOperationFinished());

        })
        .catch((error) => {
          const {
            code,
            message
          } = error;
          console.log("error", message);

          dispatch(authOperationFailed(err));

        });

    }

  };
};

共有1个答案

赵辉
2023-03-14

你必须发出你的声音

export const toggleTwitterAuthState =  (twitterIsCurrentlyLinked, contributorUserId) => dispatch => {
  let actionName = "";
  if (twitterIsCurrentlyLinked) {
    console.log("Unlinking twitter");
    actionName = "TWITTER_UNLINK";
    unlinkTwitterAccount(contributorUserId);
  } else {
    console.log("Linking twitter");
    dispatch(linkTwitterAccount(contributorUserId));
    actionName = "TWITTER_LINK";
  }
};
 类似资料:
  • 问题内容: 未处理的拒绝(错误):动作必须是普通对象。使用自定义中间件进行异步操作。 我想在每个帖子中添加评论。因此,当获取帖子运行时,我想为所有帖子调用获取评论API。 问题答案: 您必须在异步请求结束后分派。 这将工作:

  • 我正在用。NET核心编写一个ASP.NET MVC站点。我试图封装一些常见的异常处理。在基类中,我有这个方法。 从继承自该基类的控制器中,我使用如下方法: 假设_someservice.getAsync()方法如下: 这工作得很好,将捕获基类方法中的异常并返回NotFound结果。 但是,我希望避免从SomeService.GetAsync方法调用。result。我读到的任何地方都说不要那样做,因

  • 问题内容: 我不确定如何处理这种情况,因为我是iOS开发和Swift的新手。我正在像这样执行数据获取: 我的loadShows()函数解析从加载到UIWebView的网站中获取的大量数据。问题是我在loadShows函数中有一个等待10秒钟左右的计时器。这允许页面中的javascript在开始解析数据之前完全加载。我的问题是完成处理程序在我的loadShows()之前完成。 我想做的是为“ isC

  • 概述 定时器 Promise 对象

  • 问题内容: 给出以下代码: 产生以下错误: TS2322:类型’Promise []’无法分配给类型’number []’。类型’Promise 不可分配给类型’number’。 我该如何解决?怎样才能让和一起工作? 问题答案: 这里的问题是,您正在尝试兑现承诺而不是承诺。这没有达到您的期望。 当传递给的对象不是Promise时,只需立即按原样返回值,而不是尝试解析它。因此,由于您在此处传递了(P

  • 使用spray时,我一直遇到相同的设计问题,即在Akka中执行一些异步(tell)操作之后,如何为请求找到spray http请求的原始上下文。 我使用的是Net-a-Porter actor per request模型。它创建了一个子执行元,我指定该子执行元来处理每个请求,该子执行元由另一个包含正确请求上下文的执行元进行封装。