在useEffect挂钩中调用异步函数,但会出错

时间:2020-06-14 17:30:26

标签: reactjs react-native react-redux

我具有从本地存储获取访问令牌的功能,如果找到,则向用户显示主屏幕,否则,显示登录屏幕。该函数在名为utils.js的js文件中定义。这是函数:

const tryLocalSignin = (dispatch) => async () => {
  const token = await AsyncStorage.getItem("token");
  if (token) {
    console.log("Got token from AsyncStorage!");
    dispatch(signInFulfilled(token));
    navigate("mainFlow");
  } else {
    console.log("No token got from AsyncStorage...");
    navigate("loginFlow");
  }
};

在我的SigninScreen.js中,我想首先运行上述功能,以便在找到令牌的情况下可以直接导航到主屏幕。这是我的SigninScreen.js的一部分

const SigninScreen = ({ token, error, dispatch }) => {
  // use the useEffect hook to run the tryLocalSignin() once.
  useEffect(() => {
    dispatch(utils.tryLocalSignin());
  }, []);

  return (<View>...</View>)
  ...
  export default connect(mapStateToProps, mapDispatchToProps)(SigninScreen). // redux way to connect to storage

当我启动登录屏幕时,可以从日志中看到代码已成功从存储中获取令牌,但同时也出现错误:

Try local signin
Got token from AsyncStorage!

[Unhandled promise rejection: TypeError: dispatch is not a function. (In 'dispatch((0, _authActions.signInFulfilled)(token))', 'dispatch' is undefined)]
* src/utils.js:63:13 in <anonymous>
- node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
- node_modules/regenerator-runtime/runtime.js:274:30 in invoke

为什么会出现此错误?如何摆脱它?

2 个答案:

答案 0 :(得分:0)

我建议您使用像这样的react-redux钩子:

import React,{useEffect} from "react"
import {useSelector,useDispatch} from "react-redux"
import utils from "./utils"

    const SigninScreen = () => {
     const {token,error} = useSelector(state=>state)
     const dispatch = useDispatch()
      useEffect(() => {
        dispatch(utils.tryLocalSignin());
      }, []);

      return (<View>...</View>)
      ...
      export default SigninScreen

如果您使用的是异步操作,则需要使用redux异步中间件来启用此安装redux-thunk

npm i redux-thunk

然后在您的商店中使用:

import thunk from redux-thunk 
import { createStore, applyMiddleware } from 'redux';
const store = createStore(rootReducer, applyMiddleware(thunk));

答案 1 :(得分:0)

尝试使用类似

const [value,setDispatch] = useState(false);

,然后在useEffect()中使用setDispatch(true)