javascript - 如何从 redux thunk 操作返回 promise 并在组件中使用它

标签 javascript reactjs redux firebase-authentication redux-thunk

我正在使用 React+Redux+Redux Thunk + Firebase 身份验证。在 Typescript 中编写代码。 我的行动是:

//Type for redux-thunk. return type for rdux-thunk action creators
type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  IStoreState, //my store state
  null,
  Action<userActionTypes>
>

export const signInWithEmailAndPasword =(email:string, pasword:string): AppThunk=>{
  return async (dispatch)=>{
    auth.signInWithEmailAndPassword(email, pasword).then(response=>{
      if(response.user){
        const docRef = db.collection("users").doc(response.user.uid);
          docRef.get().then(function(doc) {
            if (doc.exists) {
              const userData = doc.data(); //user data from firebase DB
               //if user exists in DB, dispatch
               dispatch({
                type: userActionTypes.SIGN_IN_USER,
                payload: userData
              })
              return userData;
            } else {
                // doc.data() will be undefined in this case
                console.log("No such document!");
            }
        }).catch(function(error) {
            console.log("Error getting document:", error);
        });
      }
    })
    .catch(err=> dispatch(setUserError(err.message)))
  }
}

我的登录组件,我在其中调度上述操作:

import React, { useState } from 'react'
//some other imports
//...
//
import { useDispatch, useSelector } from 'react-redux';
import { signInWithEmailAndPasword } from '../../redux/actions/userActions';


interface ISignInState {
  email: string;
  password: string;
}
const SignIn = (props:any) => {

  const [values, setValues] = useState<ISignInState>({ email: '', password: '' })

  const dispatch = useDispatch();

  const handleInputChange = (e: React.FormEvent<HTMLInputElement>): void => {
    const { name, value } = e.currentTarget;
    setValues({ ...values, [name]: value })
  }

  const handleFormSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    const { email, password } = values;
    dispatch(signInWithEmailAndPasword(email, password))
//// -> gives error: Property 'then' does not exist on 
//// type 'ThunkAction<void, IStoreState, null, Action<userActionTypes>>'
    .then(()=>{ 
      props.history.push('/');
      setValues({ email: '', password: '' })
    })

  }

  return (<div>Sign in UI JSX stuff</div>)

所以当我尝试使用.then()时之后dispatch(signInWithEmailAndPasword(email, password))它给出了错误 Property 'then' does not exist on type 'ThunkAction<void, IStoreState, null, Action<userActionTypes>>' 那么我如何从 redux 操作返回 promise 并链接 .then()在上面?我总是假设 thunk 操作默认返回 promise 。 感谢您的帮助 编辑: 临时解决方案是使用any作为上述操作的返回类型:

export const signInWithEmailAndPasword = (email:string, pasword:string):any =>{
  return async (dispatch: any)=>{
    try {
      const response = await auth.signInWithEmailAndPassword(email, pasword)
      if(response.user){
        const userInDb = await getUserFromDB(response.user)
        dispatch(userSignIn(userInDb))
        return userInDb
      }
    } catch (error) {
      dispatch(setUserError(error.message))
    }
  }
}

但我不想使用any

最佳答案

只需在此行之前添加 return 即可:

auth.signInWithEmailAndPassword(email, pasword).then(response=>{

所以会是:

export const signInWithEmailAndPasword =(email:string, pasword:string): AppThunk=>{
  return async (dispatch)=>{
    return auth.signInWithEmailAndPassword(email, pasword).then(response=>{

它应该可以工作。

关于javascript - 如何从 redux thunk 操作返回 promise 并在组件中使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59079667/

相关文章:

javascript - $_POST 未读取 Axios 发布参数

reactjs - 在 Semantic-UI-React 中导入 CSS

angular - 效果 "AuthEffects.authLogin$"发送无效操作 : undefined

javascript - UrlSearchParams.get() 不适用于重写的网址

javascript - Select2 3.5.2 mousedown在IE10 & IE11中跳转到列表顶部

javascript - 创建对象时返回PromiseValue

javascript - 使用 redux 和 thunk 返回嵌套状态

javascript - $q.all 在收到 404 响应时中止所有 promise

javascript - 在 React 样式组件上使用 'ref' 不起作用

javascript - 组件渲染乱序