2017-09-03 128 views
0

所以我有這個問題,其中一個變量更新比路由變化慢。 當我有一個錯誤,例如我的註冊視圖,錯誤立即顯示。當按回到登錄視圖時,錯誤正在通過動作重置爲(對「componentWillUnmount」操作「clearErrors」)爲空字符串。問題是,我可以在它收到新的空錯誤狀態之前暫時登錄登錄的錯誤消息。減速狀態更新

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

如果不查看渲染代碼是不可能的,但很可能緩慢並不是由於redux更新狀態所需的時間而引起的,而是React在調度完成後重新呈現UI - 可能是因爲當您的導航器正在轉換時,它正忙於重新渲染其他內容。

爲了保證動作的順序與redux-thunk,你可以從你的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

我懷疑這是問題所在。人們在render中針對.bind()發出警告的原因是它會創建不必要的函數實例,並且可能會與子組件的shouldComponentUpdate檢查混淆。這兩者都不會引起性能問題,而我從來沒有見過任何人支持.bind()引起的緩慢,實際上它們是以真正的基準測試來支持的。 – jevakallio

+0

我明白了..我用更多的代碼更新了我的主帖。 LoginForm.js是我正在導航的組件,它在很短的時間內顯示組件。你介意看一下嗎? –