2017-09-03 23 views
0

私は、この問題は、変数の更新がルート変更よりも遅い場合に発生します。 たとえば、登録ビューでエラーが発生すると、エラーがすぐに表示されます。戻るを押してログインビューに戻ると、エラーがリセットされます(アクション "clearErrors"がcomponentWillUnmountで実行中)アクションを介して空の文字列にリセットされています。問題は、新しい空のエラー状態を受け取る前に、ログイン時にエラーメッセージをしばらく表示できることです。遅い状態での更新遅い

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 />; 
}; 

私はすべてのconsole.logsが削除された、プロダクションビルドのデバイスOnePlus3で動作しています。

私が読んだことから、これは速くなければなりません。私はここで何か間違っていますか?

答えて

3

レンダリングコードを見ずに言うことはできませんが、遅さは状態を更新するために要する時間に起因するものではなく、Reactがディスパッチ完了後にUIを再レンダリングするためですあなたのナビゲータが移行している間に他のものを再描画することが忙しいからです。

redux-thunkとアクションの順序を保証するために、あなたはサンクアクションの作成者からの約束を返すと、アクションがディスパッチされるまで戻ってナビゲートするのを待つことができます。

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

あなたのビューで、その後、あなたが行うことができますエラーが解消された後のナビゲーション操作:

// 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

私はそれが問題だとは思っていません。人々がレンダリングで.bind()を警告する理由は、不要な関数インスタンスを作成し、おそらく子コンポーネントのshouldComponentUpdateチェックを混乱させるためです。どちらも、ここでperf問題を引き起こすことはありません。実際のベンチマークでは遅くなっている.bind()が実際にそれを戻すという主張は誰も見たことがありません。 – jevakallio

+0

私は参照してください..私はいくつかのコードで私のメインポストを更新しました。私が戻ってくるコンポーネントであるLoginForm.jsは、非常に短い時間の間、のコンポーネントを示しています。あなたは見てみましょうか? –

関連する問題