2017-02-14 5 views
1

React, Redux 및 Redux-Thunk가있는 프로젝트에서 로그인 양식으로 작업하고 있습니다. Redux-Thunk를 사용하여 제출 된 로그인 양식을 백엔드에 전달하고 유효성을 검사 한 데이터를 감속기를 통해 다시 상태로 가져 오는 것과 같은 비동기 작업을 전달할 수 있습니다. 구성 요소가 필요한 데이터를 얻으면 문제없이 필요한 페이지로 리디렉션 할 수 있습니다.React 구성 요소 내 비동기 작업

문제는 사용자를 리디렉션하기 직전에 비동기 네트워크 요청에서 나온 일부 데이터를 localStorage에 작성해야한다는 것입니다. 이 비동기 작업을 수행하지 않으면 사용자는 로컬 저장소에 기록 된 초기 상태 값으로 리디렉션됩니다.

해결 방안으로 들어오는 데이터를 기다리기 위해 React 구성 요소에서 약속 및 시간 제한을 사용하고 있습니다.

이 접근 방식은 작동하는 것처럼 보이지만 올바르게 느끼지 못합니다. 누군가 제게 더 나은 연습을 제안 할 수 있습니까?

다음은 구성 요소의 코드입니다. 여기서는 가능한 한 짧게 만들기 위해 관련성없는 것들을 대부분 필터링했습니다.

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); 

답변

1

은 지금까지 나는 localStorage.seItem 동기입니다 알고 그래서 당신은 리디렉션하기 전에 스토리지 기능 저장 데이터를 호출 할 수 있습니다.

+0

문제는 작성 될 값이 초기 상태에서 null로 정의된다는 것입니다. 약속을 사용하지 않거나 시간 제한을 사용하지 않으면 초기 상태 값이 리디렉션 전에 기록됩니다. (질문에 이것을 추가하십시오.) – cinnaroll45

+2

당신은 'handleValidLogin'을 조기에 호출하는 것처럼 들립니다. 필요한 모든 소품이 도착할 때까지'handleValidLogin'을 호출하지 마십시오. 예 : 'if (nextProps.token && nextProps.username && nextProps.id) {this.handleValidLogin(); }' – Brandon

+0

맞아요. 브랜든, 한번 해보겠습니다. – cinnaroll45