2017-09-03 63 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是我正在导航的组件,它在很短的时间内显示组件。你介意看一下吗? –