javascript - React 组件中的异步操作

标签 javascript reactjs asynchronous redux redux-thunk

我正在使用 React、Redux 和 Redux-Thunk 的项目中开发登录表单。使用 Redux-Thunk,我能够调度异步操作,例如将提交的登录表单传递到后端并通过 reducer 将经过验证的数据带回状态。一旦组件获取了它需要的数据,它就可以毫无问题地重定向到它需要的页面。

问题是,在重定向用户之前,我需要将一些来自异步网络请求的数据写入本地存储。如果我不执行此异步操作,用户将被重定向,并将初始状态值写入本地存储。

作为解决方案,我在 React 组件中使用 Promise 和超时来等待传入数据。

这种方法似乎有效,但感觉不太对劲,有人可以建议我更好的做法吗?

这是组件中的代码,我过滤了大部分不相关的内容,使其尽可能简短。

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {browserHistory} from 'react-router';
import {reduxForm} from 'redux-form';
import {connect} from 'react-redux';

import {validate} from './../utils/login/surfaceValidation';
import {inputAlerts} from './../utils/login/inputAlerts';

import {submitLogin} from './../redux/actions/index';

class Form extends Component {

    componentWillReceiveProps(nextProps) {
        if(nextProps.loginApproved) {
            this.handleValidLogin();
        }
    }

    handleLogin(props) {
        this.props.submitLogin(props);
        // submitLogin is async action handled by redux-thunk it returns
        // this.props.loginApproved and if it's true componentWillReceiveProps
        // will trigger.
    }

    handleValidLogin() {
        this.writeToStorage()
        .then(() => {
            browserHistory.push('/main');
        }).catch((err) => {
            console.log(err);
        });
    }

    writeToStorage(){
        return new Promise((resolve, reject) => {
            setTimeout(() =>{
                localStorage.setItem('user',
                    JSON.stringify({
                        authenticated: true,
                        username: this.props.username,
                        id: this.props.id,
                        token: this.props.token
                    }));
            }, 3000);
            setTimeout(() => {
                if(this.props.token != null) {
                    resolve();
                    console.log('got a token - resolving.');
                } else {
                    reject();
                    console.log('no token - rejecting. ');
                }
            }, 4000);
        });
    }

    render() {

        return (
            // Login form component is here.
            // When user submits form, this.handleLogin() is called. 
        );
    }
}


function mapDispatchToProps(dispatch){
    return bindActionCreators({submitLogin});
}

function mapStateToProps(state) {
    return {
        loginApproved: state.login.loginApproved,
        username: state.login.username,
        id: state.login.id,
        token: state.login.token
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(Form);

最佳答案

据我所知 localStorage.setItem 是同步的,因此您可以在重定向之前调用将数据保存到存储的函数。

关于javascript - React 组件中的异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42228523/

相关文章:

javascript - 发现 AngularJS 循环依赖项 : $http <- Auth <- AuthInterceptor <- $http <- $templateRequest <- $compile

javascript - 如何从 servlet 中隐藏基于数组或数组列表的 div

c# - 如何正确覆盖自定义 SynchronizationContext 中的 Post 方法?

c# - IProgress<T> 不会在当前上下文中触发事件

c# - 从 C# 调用 C++ 函数并将数据发送回 C#

javascript - 创建一系列独特的组合

javascript - JavaScript 中有没有办法监听控制台事件?

reactjs - 从 Jest 测试中访问 useState 值

javascript - react |使用创建选择器传递 Redux 状态并隐藏菜单项

javascript - React Material-UI GridList层叠布局