2017-06-26 115 views
0

所以我對React Native很新,對於redux也是全新的。我創建了一個使用條件React Navigation渲染的驗證流程,除了提供錯誤外,我相信這是由競爭條件引起的。它會檢查用戶是否登錄並根據他們是否登錄進行渲染。但是,如果用戶已經登錄,它將開始呈現LoginScreen,檢測到它們已登錄,然後嘗試重新呈現,導致出現以下錯誤:React Native Redux條件LoggedIn渲染導致競爭條件

「Warning:setState(...):Can only更新掛載或掛載的組件,這通常意味着你在卸載的組件上調用了setState(),這是一個no-op,請檢查Icon組件的代碼。

我的主要成分是這樣的:

import React, { Component } from "react"; 
 
import { StyleSheet, Text, View, AsyncStorage } from "react-native"; 
 
import { connect, Provider } from "react-redux"; 
 
import Reactotron from "reactotron-react-native"; 
 

 
import { logIn } from "../actions"; 
 
import { SignedIn, SignedOut } from "../components/Nav"; 
 
import { isSignedIn } from "../components/Auth"; 
 
import LoginScreen from "../containers/LoginScreen"; 
 

 
class RootApp extends Component { 
 
    async checkSignedIn() { 
 
     res = await isSignedIn(); 
 
     if (res != false) { 
 
      expires = String(res.expires); 
 
      this.props.logIn(res.fbToken, expires); 
 
     } else { 
 
      console.log("Not logged in"); 
 
     } 
 
    } 
 

 
    async componentWillMount() { 
 
     await this.checkSignedIn(); 
 
    } 
 

 
    render() { 
 
     if (this.props.auth.signedIn == true) { 
 
      return <SignedIn />; 
 
     } else { 
 
      return <SignedOut />; 
 
     } 
 
    } 
 
} 
 

 
const styles = StyleSheet.create({ 
 
    container: { 
 
     flex: 1, 
 
     backgroundColor: "#fff", 
 
     alignItems: "center", 
 
     justifyContent: "center", 
 
     fontSize: 96 
 
    } 
 
}); 
 

 
const mapStateToProps = state => { 
 
    return { 
 
     auth: state.auth 
 
    }; 
 
}; 
 

 
const mapDispatchToProps = dispatch => { 
 
    return { 
 
     logIn: fbToken => { 
 
      dispatch(logIn(fbToken, expires)); 
 
     } 
 
    }; 
 
}; 
 

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

資產淨值看起來像

import React, { Component } from "react"; 
 
import { TabNavigator, StackNavigator } from "react-navigation"; 
 
import Tasks from "../screens/Tasks"; 
 
import Home from "../screens/Home"; 
 
import Message from "../screens/Message"; 
 
import Profile from "../screens/Profile"; 
 
//import WelcomeScreen from "../screens/WelcomeScreen"; 
 
import PhoneContacts from "../screens/PhoneContacts"; 
 
import { SimpleLineIcons } from "@expo/vector-icons"; 
 
import LoginScreen from "../containers/LoginScreen"; 
 

 
const InviteNavigator = StackNavigator({ 
 
    DeathMessage: { screen: Message }, 
 
    PhoneContacts: { screen: PhoneContacts } 
 
}); 
 

 
export const SignedIn = TabNavigator({ 
 
    Tasks: { 
 
     screen: Tasks, 
 
     navigationOptions: { 
 
      tabBarIcon: ({ tintColor }) => 
 
       <SimpleLineIcons name="list" size={30} /> 
 
     } 
 
    }, 
 
    Home: { 
 
     screen: Home, 
 
     navigationOptions: { 
 
      tabBarIcon: ({ tintColor }) => 
 
       <SimpleLineIcons name="home" size={30} /> 
 
     } 
 
    }, 
 
    Message: { 
 
     screen: InviteNavigator, 
 
     navigationOptions: { 
 
      tabBarIcon: ({ tintColor }) => 
 
       <SimpleLineIcons name="envelope-letter" size={30} /> 
 
     } 
 
    }, 
 
    Profile: { 
 
     screen: Profile, 
 
     navigationOptions: { 
 
      tabBarIcon: ({ tintColor }) => 
 
       <SimpleLineIcons name="user" size={30} /> 
 
     } 
 
    } 
 
}); 
 

 
export const SignedOut = StackNavigator({ 
 
    SignIn: { 
 
     screen: LoginScreen, 
 
     navigationOptions: { 
 
      title: "Sign In" 
 
     } 
 
    } 
 
});

LoginScreen樣子:

import { connect } from "react-redux"; 
 
import React, { Component } from "react"; 
 
import { 
 
    Button, 
 
    View, 
 
    Text, 
 
    ActivityIndicator, 
 
    Alert, 
 
    FlatList 
 
} from "react-native"; 
 
import { NavigationActions } from "react-navigation"; 
 
import { SocialIcon, Card } from "react-native-elements"; 
 
import Reactotron from "reactotron-react-native"; 
 
import { AsyncStorage } from "react-native"; 
 

 
import { logIn } from "../actions"; 
 
import { signIn } from "../components/Auth"; 
 

 
class SignIn extends Component { 
 
    async handleClick() { 
 
     res = await signIn(); 
 
     if (res.type == "success") { 
 
      expires = String(res.expires); 
 
      AsyncStorage.setItem("fbToken", res.token); 
 
      AsyncStorage.setItem("expires", expires); 
 
      this.props.logIn(res.token, expires); 
 
     } else { 
 
      console.log("Login Failed"); 
 
     } 
 
    } 
 

 
    render() { 
 
     return (
 
      <View style={{ paddingVertical: 20 }}> 
 
       <Card title="finis Requires A Facebook Account To Operate"> 
 
        <SocialIcon 
 
         title="Fred" 
 
         button 
 
         type="facebook" 
 
         onPress={() => this.handleClick()} 
 
        /> 
 
       </Card> 
 
      </View> 
 
     ); 
 
    } 
 
} 
 

 
const mapDispatchToProps = dispatch => { 
 
    return { 
 
     logIn: fbToken => { 
 
      dispatch(logIn(fbToken, expires)); 
 
     } 
 
    }; 
 
}; 
 

 
LoginScreen = connect(null, mapDispatchToProps)(SignIn); 
 

 
export default LoginScreen;

任何幫助將不勝感激。如果指向正確的方向,很樂意徹底重新設計。

+0

哪裏是'Icon'分量代碼? –

+0

現在排序謝謝 –

回答

0

通過添加auth.checking道具並渲染活動微調器直到它已被檢查進行排序。

render() { 
 
     if (this.props.auth.checking == true) { 
 
      return (
 
       <ActivityIndicator 
 
        animating={true} 
 
        style={styles.activityIndicator} 
 
        size="large" 
 
       /> 
 
      ); 
 
     } else if (this.props.auth.signedIn == true) { 
 
      return <SignedIn />; 
 
     } else { 
 
      return <SignedOut />; 
 
     } 
 
    }