redux 状态更新缓慢

Slow state update in redux

所以我遇到了变量更新比路由更改慢的问题。 例如,当我的注册视图出现错误时,该错误会立即显示出来。当按返回返回登录视图时,错误正在通过操作重置 (在 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="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 已删除,生产版本。

根据我的阅读,这应该很快。我是不是做错了什么?

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

为了保证 redux-thunk 的动作顺序,您可以 return 来自您的 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());