2017-09-03 6 views
0

그래서 변수 업데이트가 경로 변경보다 느린이 문제가 있습니다. 예를 들어 등록보기에서 오류가 발생하면 즉시 오류가 표시됩니다. 다시 로그인 화면으로 돌아 가면 오류가 재설정됩니다 (조치 "clearErrors"가 componentWillUnmount에서 실행 중임)을 조치를 통해 빈 문자열에 재설정 중입니다. 문제는 새로운 빈 오류 상태를 받기 전에 잠시 동안 로그인시 오류 메시지를 볼 수 있다는 것입니다.redux에서 느린 상태 업데이트

ErrorReducer.js

import { 
    ERROR, 
    CLR_ERROR 
} from '../actions/types'; 

const INIT_STATE = { 
    error: '' 
}; 

export default (state = INIT_STATE, action) => { 
    switch (action.type) { 
     case ERROR: 
      return { ...state, error: action.payload }; 
     case CLR_ERROR: 
      return { ...state, error: '' }; 
     default: 
      return state; 
    } 
}; 

error.js (행동)

import { CLR_ERROR } from './types'; 

export const clearErrors =() => { 
    return (dispatch) => { 
     dispatch({ type: CLR_ERROR }); 
    }; 
}; 

LoginForm.js

import React, { Component } from 'react'; 
import { View } from 'react-native'; 
import { Actions } from 'react-native-router-flux'; 
import { connect } from 'react-redux'; 
import { emailChanged, passwordChanged, loginUser, resetRoute, autoLogin } from '../actions'; 
import { Button, Input, Message } from './common'; 

class LoginForm extends Component { 

    componentWillUnmount() { 
     this.props.resetRoute(); 
    } 

    onEmailChange(text) { 
     this.props.emailChanged(text); 
    } 

    onPasswordChange(text) { 
     this.props.passwordChanged(text); 
    } 

    onButtonPress() { 
     this.props.loading = true; 
     const { email, password } = this.props; 
     this.props.loginUser({ email, password }); 
    } 

    render() { 
     return (
      <View 
       style={{ 
        flex: 1, 
        marginLeft: 10, 
        marginRight: 10, 
        flexDirection: 'column', 
        justifyContent: 'center', 
        alignItems: 'center' 
       }} 
       keyboardShouldPersistTaps="always" 
       keyboardDismissMode="on-drag" 
      > 

       <Message 
        type="danger" 
        message={this.props.error} 
       /> 

       <Input 
        placeholder="[email protected]" 
        keyboardType="email-address" 
        returnKeyType="next" 
        onChangeText={this.onEmailChange.bind(this)} 
        value={this.props.email} 
        icon="ios-mail" 
       /> 
       <Input 
        secureTextEntry 
        placeholder="ditt lösenord" 
        onChangeText={this.onPasswordChange.bind(this)} 
        value={this.props.password} 
        icon="ios-key" 
        iconSize={22} 
       /> 

       <Button 
        loading={this.props.loading} 
        uppercase 
        color="primary" 
        label="Logga in" 
        onPress={this.onButtonPress.bind(this)} 
       /> 

       <Button 
        fontColor="primary" 
        label="Registrera" 
        onPress={() => Actions.register()} 
       /> 
       <Button 
        fontColor="primary" 
        label="Glömt lösenord" 
        onPress={() => Actions.resetpw()} 
       /> 

      </View> 
     ); 
    } 

} 

const mapStateToProps = ({ auth, errors }) => { 
    const { email, password, loading, token } = auth; 
    const { error } = errors; 
    return { email, password, error, loading, token }; 
}; 

export default connect(mapStateToProps, { 
    emailChanged, passwordChanged, loginUser, resetRoute, autoLogin 
})(LoginForm); 

Message.js (구성 요소가 표시하는 오류)

import React from 'react'; 
import { View, Text } from 'react-native'; 
import Icon from 'react-native-vector-icons/Ionicons'; 
import { colors } from '../style'; 

export const Message = ({ type, message }) => { 
    const style = { 
     view: { 
      alignSelf: 'stretch', 
      flexDirection: 'row', 
      justifyContent: 'center', 
      alignItems: 'center', 
      padding: 20, 
      margin: 15, 
      backgroundColor: colors[type], 
      borderRadius: 3, 
      elevation: 5, 
      shadowRadius: 5, 
      shadowColor: colors.smoothBlack, 
      shadowOffset: { width: 2.5, height: 2.5 }, 
      shadowOpacity: 0.5 
     }, 
     text: { 
      color: colors.alternative, 
      fontSize: 12, 
      alignSelf: 'center', 
      flex: 1 
     }, 
     icon: { 
      marginRight: 20, 
      marginLeft: 0, 
      marginTop: 2, 
      alignSelf: 'center' 
     } 
    }; 
    const getIcon = (iconType) => { 
     switch (iconType) { 
      case 'info': 
       return 'ios-information-circle'; 
      case 'success': 
       return 'ios-checkmark-circle'; 
      case 'danger': 
       return 'ios-alert'; 
      case 'warning': 
       return 'ios-warning'; 
      default: 
       return; 
     } 
    }; 
    if (message.length > 0) { 
     return (
      <View style={style.view}> 
       {(type) ? <Icon name={getIcon(type)} size={20} style={style.icon} /> : null} 
       <Text style={style.text}>{message}</Text> 
      </View> 
     ); 
    } 
    return <View />; 
}; 

OnePlus3 디바이스에서 모든 console.logs를 제거하고 프로덕션 빌드를 실행하고 있습니다.

내가 읽은 것부터 빠릅니다. 내가 여기서 뭔가 잘못하고있는거야?

답변

3

렌더링 코드를 보지 않고 말할 수는 없지만 지연이 상태를 업데이트하는 데 걸리는 시간 때문이 아니라 디스패치가 완료된 후 React가 UI를 다시 렌더링하는 것이 원인 일 수 있습니다 - 아마도 네비게이터가 전환하는 동안 다른 것들을 다시 렌더링하기 때문에. 당신이 할 수있는,

export const clearErrors =() => { 
    return (dispatch) => { 
     return new Promise(dispatch({ type: CLR_ERROR })); 
    }; 
}; 

보기에서 다음 :

당신이 당신의 썽크 행동 작성자에서 약속을 반환하고 조치가 전달 될 때까지 다시 탐색 할 수 기다릴 수, redux-thunk과 행동의 순서를 보장하려면 오류가 해결되면 뒤로 내비게이션 동작 :

// assuming the action creator has been passed 
// to the component as props 
this.props.clearErrors().then(() => navigator.back()); 
+0

내 구성 요소에는 약간의 바인딩이 있습니다. 나는 그것이 렌더링 속도를 늦추 게 할 것이라고 최근에 읽었는데 아마도 그렇게 될 것입니다. onChangeText = {this.onEmailChange.bind (this)} –

+0

그게 문제인지 의심 스럽네. 사람들이 render에서 .bind()에 대해 경고하는 이유는 불필요한 함수 인스턴스를 생성하고 자식 구성 요소의 shouldComponentUpdate 검사를 망칠 가능성이 있기 때문입니다. 어느 쪽도 퍼프 문제를 여기에서 일으키지 않을 것이고, 느린 것을 유발하는 .bind()가 실제로 실제 벤치 마크를 통해이를 되돌려 놓았다는 주장을 본 사람은 본 적이 없습니다. – jevakallio

+0

나는 메인 코드를 더 많은 코드로 업데이트했다. LoginForm.js는 다시 탐색하는 구성 요소이며 매우 짧은 순간에 구성 요소를 표시합니다. 좀 봐도 될까요? –