为什么有时本机redux reducer被调用两次,有时仅被调用一次?

时间:2018-11-24 23:51:05

标签: javascript reactjs react-native redux react-redux

我正在使用React Native应用程序。我仍然对接触本地人和对世界做出反应还很陌生,所以我在这里可能做错了一些我不知道但我需要帮助的事情。因此,当我尝试更新reducer状态时,我的应用程序中现在正在发生什么,它两次调用它,两次更新。

这就是我想要做的,

1) When app opens, set default `deviceData` object.
2) Check for internet connection and update device data.
3) I disable internet that updates `deviceData` object once.
4) I enable internet and that updates `deviceData` object twice where it comes back as false.

这是我的代码,

NoInternet.js文件

import React, {PureComponent} from 'react';
import {View, Text, NetInfo, Dimensions, StyleSheet} from 'react-native';
import {statusBarHeight} from "./AppBar";
import {RED_DARKEN_THREE} from "./colors";
import {connect} from "react-redux";
import {updateInternetState} from '../actions/internetStateChangeAction';

const {width} = Dimensions.get('window');

function MiniOfflineSign() {
    return (
        <View style={styles.offlineContainer}>
            <Text style={styles.offlineText}>No Internet Connection</Text>
        </View>
    );
}

class OfflineNotice extends PureComponent {
    state = {
        isConnected: true
    };

    componentDidMount() {
        NetInfo.isConnected.addEventListener('connectionChange', this.handleConnectivityChange);
    }

    componentWillUnmount() {
        NetInfo.isConnected.removeEventListener('connectionChange', this.handleConnectivityChange);
    }

    handleConnectivityChange = isConnected => {
        this.setState({isConnected});
        this.props.updateConnectivityChange({isConnected});
    };

    render() {
        if (!this.state.isConnected) {
            return <MiniOfflineSign/>;
        }
        return null;
    }
}

const styles = StyleSheet.create({
    offlineContainer: {
        backgroundColor: RED_DARKEN_THREE,
        height: 30,
        justifyContent: 'center',
        alignItems: 'center',
        flexDirection: 'row',
        width,
        position: 'absolute',
        top: statusBarHeight,
    },
    offlineText: {
        color: '#fff',
        fontFamily: "Muli-Regular",
    }
});

function mapStateToProps(state, {navigation}) {
    return {
        state,
        navigation
    };
}
const mapDispatchToProps = dispatch => ({
    updateConnectivityChange: ({isConnected}) => {
        dispatch(updateInternetState({isConnected}));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(OfflineNotice);

internetStateChangeAction.js文件

export const UPDATE_INTERNET_STATE = 'UPDATE_INTERNET_STATE';

export const updateInternetState = data => ({
    type: UPDATE_INTERNET_STATE,
    data,
});

deviceReducer.js文件

import {Platform} from 'react-native';
import {UPDATE_INTERNET_STATE} from '../actions/internetStateChangeAction';

const deviceData = {
    deviceType: Platform.OS,
    deviceID: null,
    isInternetAvailable: true,
};


const deviceDataReducer = (state = deviceData, action) => {
    switch (action.type) {
        case UPDATE_INTERNET_STATE:
            return {
                ...state,
                isInternetAvailable: action.data.isConnected
            };
        default:
            return state;
    }
};

export default deviceDataReducer;

这是我的调试日志,

enter image description here

如您所见,有四个动作日志。

1) First action is default when app is opened and it is called to check internet connection.
2) Second action is when I disable internet in my iMac by disconnecting from wifi (I am developing this app on iMac and using iOS simulator)
3) HERE IS THE MOST IMPORTANT PART, I should see only one action when I enable wifi access in my iMac and connect to internet. Which happens as third action and internet connection as true
4) But there is fourth action called automatically which returns false and that fails everything.

如果我再次禁用互联网并再次启用,它将再次被调用两次,并且得到以下结果,

enter image description here

我不知道我在哪里做错什么!

谢谢大家!

2 个答案:

答案 0 :(得分:2)

NetInfo组件存在一个已知问题。第一次重新连接后,它似乎返回false。我会改变你的方式。您需要记住,NetInfo会通知是否存在与WiFi或3G之类的Internet的协议连接,但不会通知是否可以通过Internet进行数据传输。您可以通过使WIFI保持连接状态并从Internet调制解调器上拔下数据电缆来尝试此操作。 Wifi信号仍然存在,但无法通过Internet传输数据,但是NetInfo应该重做。

我和你有同样的问题。每次启动应用程序时,我都想确保是否有互联网。我的解决方案是在首次启动应用程序时通过fetch or axios致电www.google.com。如果失败,则表示没有互联网连接或数据传输。您还应该为互联网连接速度过慢设置超时时间。最终,每次我必须通过Internet发出请求时,我都会尝试用Promise的catch方法处理该错误。

答案 1 :(得分:1)

谢谢大家在这里帮助我。就像Helmer提到的,它是react native的已知错误,每次我得到handleConnectivityChange = isConnected时,我最终都使用Axios检查false中的互联网连接。当我的应用程序与互联网断开连接并尝试连接到Google时,我每隔5秒钟在后台运行axios代码,因此,如果遇到任何错误或响应不是200,则在5点后再次调用handleConnectivityChange函数秒钟,然后不断重复该过程,直到我可以访问Google。