redux

时间:2017-09-03 11:39:53

标签: react-native redux redux-thunk

所以我遇到这个问题,其中变量更新比路由更改慢。 当我在注册视图中出现错误时,错误会立即显示。当按回以返回登录视图时,错误正在通过操作将(在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(actions)

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="din@email.se"
                    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,生成版本。

据我所知,这应该很快。我在这里做错了吗?

1 个答案:

答案 0 :(得分:4)

如果不查看渲染代码,就不可能说,但是缓慢不是由redux更新状态所花费的时间引起的,而是React在调度完成后重新渲染UI时 - 可能是因为当你的导航器正在转换时,它正忙于重新渲染其他东西。

为了保证redux-thunk行动的顺序,你可以从你的thunk行动创建者那里返回一个Promise,然后等待导航回行动,直到动作被发送:

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