javascript - 在 react redux 中重定向之前如何等待操作完成?

标签 javascript reactjs redux promise async-await

我正在尝试根据来自 redux 存储的 isLoggedin 状态让用户登录。我的登录组件从映射到 Prop 的 userLogin 操作中调度 fetchLogin 操作。

const Login = (props) => {
    const [userLogin, setUserLogin] = useState({ email: "", password: "" })

    const getValue = e => {
        e.preventDefault();
        setUserLogin({
            ...userLogin,
            [e.target.name]: e.target.value 
        });
    }

    const makeRequest = (e) => {
        e.preventDefault()
        props.userLogin(userLogin)

        if (props.isLoggedin === true) {
            console.log(Cookie.get('accessToken'))
            props.history.push('/dashboard')
        }
    }

    return (
        <Fragment>
            <Form onSubmit={makeRequest}>
                <Form.Group controlId="formBasicEmail">
                    <Form.Label>Email Address</Form.Label>
                    <Form.Control
                        type="email"
                        name="email"
                        placeholder="Enter email"
                        onChange={getValue}
                    >
                    </Form.Control>
                </Form.Group>
                <Form.Group controlId="formBasicPassword">
                    <Form.Label>Password</Form.Label>
                    <Form.Control
                        type="password"
                        name="password"
                        placeholder="Enter password"
                        onChange={getValue}
                    >
                    </Form.Control>

                </Form.Group>
                <Button
                    variant="primary"
                    type="submit"
                >
                    Login
            </Button>
            </Form>
        </Fragment>
    )
}

const mapStateToProps = (state) => ({
    isFetching: state.userReducer.isFetching,
    isLoggedin: state.userReducer.isLoggedin,
    isError: state.userReducer.isError,
    errMessage: state.userReducer.errMessage
});

const mapDispatchToProps = dispatch => ({
    userLogin: (userLogin) => {
        dispatch(fetchLogin(userLogin))
    }
});

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Login)


这里的问题是当用户单击登录时,我负责从后端登录用户的 redux 操作需要时间,并且商店更新速度不够快,无法让 userLogin 函数确认用户是登录。我知道这与 promise 有关,但我不确定如何准确地做到这一点。

您可以在下面找到我的操作,唯一重要的操作是 fetchLogin,它是从登录组件发送的操作。

export const userLoginRequest = () => {
    return {
        type: USER_LOGIN_REQUEST,
        payload: {
            isFetching: true
        }
    };
}

export const userLoginSuccess = (user) => {
    return {
        type: USER_LOGIN_SUCCESS,
        payload: {
            user: {
                ...user
            },
            isLoggedin: true,
            isFetching: false
        }
    };
}

export const userLoginFailed = () => {
    return {
        type: USER_LOGIN_FAILED,
        payload: {
            isFetching: false,
            isError: true
        }
    };
}

export const fetchLogin = (userLogin) => dispatch => {
    dispatch(userLoginRequest())
    axios.post('/login', {
        email: userLogin.email,
        password: userLogin.password
    })
        .then(response => {
            if (response.status === 200) {
             dispatch(userLoginSuccess(response.data))
            }
        }, err => {
            console.log("Error", err)
         dispatch(userLoginFailed())
    })
}

最佳答案

您可以从您的操作中返回 promise 并在它解决后设置 isLoggedin 状态:

export const fetchLogin = (userLogin) => dispatch => {
  dispatch(userLoginRequest())
  return axios.post('/login', {
      email: userLogin.email,
      password: userLogin.password
    })
    .then(response => {
      if (response.status === 200) {
        dispatch(userLoginSuccess(response.data))
      }
      return response; 
    }).catch(err => {
      console.log("Error", err)
      dispatch(userLoginFailed())
    })
}

// ...

 const makeRequest = (e) => {
   e.preventDefault()
   props.userLogin(userLogin).then(resp => {
     if (props.isLoggedin === true) {
       console.log(Cookie.get('accessToken'))
       props.history.push('/dashboard')
     }
   })
 }

此外,您还需要更新 mapDispatchToProps 以实际返回调度:

const mapDispatchToProps = dispatch => ({
    userLogin: (userLogin) => dispatch(fetchLogin(userLogin))
});

还有一件事,我刚刚意识到在这种情况下使用 promise from dispatch 正确重定向实际上是不必要的,因为可以在 useEffect 中跟踪 isLoggedin Prop

 const makeRequest = (e) => {
  e.preventDefault()
  props.userLogin(userLogin)
}

useEffect(() => {
  if (props.isLoggedin === true) {
    console.log(Cookie.get('accessToken'))
    props.history.push('/dashboard')
  }
}, [props.isLoggedin])

关于javascript - 在 react redux 中重定向之前如何等待操作完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59039450/

相关文章:

javascript - 将 href=# 更改为 javascript :

javascript - 当 reducer 函数依赖于组件 prop 时,传递给 useReducer 钩子(Hook)的 Reducer 函数会针对一次调度调用执行多次

reactjs - 为 Typescript、es6 和 Webpack 2 配置 Jest

reactjs - 比较 "Lifting state up"与 Redux,Flux 状态管理

reactjs - Redux 避免陈旧数据?

javascript - 如何在 React/Redux 应用程序中注册页面 View

javascript - 将 {Object} 的嵌套 [Array] 转换为 > {Object} | JSON文件

javascript - 在 html 文件中使用数组

javascript - ReactJS:如何将一个组件覆盖在另一个组件的元素之上?

reactjs - 如何在 Typescript 中使用 composeWithDevTools createStore 而不会出现类型错误?