首页 > 解决方案 > 在使用异步存储的 React Native 中,抽屉导航中的注销不起作用?

问题描述

我在抽屉导航中创建了注销按钮。当用户单击注销按钮时,该按钮被单击并且 Asyncstorage 也被清除,但它没有导航到登录屏幕,为什么会这样?用户点击注销按钮后,它被点击但用户没有导航到注册/登录,即登录屏幕,为什么会这样?

抽屉导航组件:

class DrawerScreen extends Component {

  logoutUser = async () => {
    console.log('Logout clicked')

      try {
        await AsyncStorage.clear();
        this.props.logout();
        this.props.navigation.closeDrawer();
        this.props.navigation.navigate('Login');
      } catch (error) {
         console.log("Error in clearing AsyncStorage", error);
      }
  }

  render () {

    const { logged_in_user } = this.props;

    return (
      <SafeAreaView style={{flex: 1}}>
        <ScrollView>

          <TouchableOpacity onPress={() => this.props.navigation.closeDrawer()}>
              <Image source={require('../../assets/images/close.png')} style={{width: 24, height: 24, resizeMode: 'contain', marginLeft: 15, marginTop: 15}}/>
          </TouchableOpacity>
    </ScrollView>

      <TouchableOpacity onPress={this.logoutUser}>
            <View style={styles.bottomDrawerItem2}>
                <Image source={require('../../assets/images/logout.png')} style={styles.drawerItemImage}/>
                <Text style={styles.drawerItemText}>Logout</Text>
            </View>
          </TouchableOpacity>
          </View>
      </SafeAreaView>
    );
  }
}

登录屏幕:

class LoginContainer extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount = async () => {
        let { navigation, logged_in_user } = this.props;

        if (!logged_in_user) {
            logged_in_user = await AsyncStorage.getItem('logged_in_user');
            logged_in_user = JSON.parse(logged_in_user);
            this.props.login(logged_in_user);
            // TODO: Check if it's correct format
        }
        if (logged_in_user) {
            navigation.navigate('SignedIn');
        }
    }

    render() {
        return <LoginView {...this.props} />;
    }
}

导航.js:

const DrawerNavigator = createDrawerNavigator({
    Home:{
        screen: TabNavigation,
    }
},
{
    initialRouteName: 'Home',
    contentComponent: DrawerScreen,
    drawerWidth: 300
},
);

    const AppStackNavigator = createStackNavigator({

        //important: key and screen name (i.e. DrawerNavigator) should be same while using the drawer navigator inside stack navigator.

        DrawerNavigator:{
            screen: DrawerNavigator,
            navigationOptions: {
                header: null
            }
        }
    });

    const SignedOutNavigator = createSwitchNavigator({
        Login: {
            screen: LoginContainer,
            navigationOptions: { header: null, gesturesEnabled: false }
        },
        SignedIn: {
            screen: AppStackNavigator,
            navigationOptions: { header: null, gesturesEnabled: false }
        }
    },
    {
        initialRouteName: 'Login',
    });

还原:

行动:

function login(logged_in_user) {
  return {
    type: LOGIN,
    logged_in_user
  };
}

function logout() {
  return {
    type: LOGOUT,
  };
}

减速器:

const initialLoginState = {
  logged_in_user: null
};

function loginReducer(state = initialLoginState, action) {
  switch (action.type) {
    case LOGIN:
      return { ...state, logged_in_user: action.logged_in_user };
    case LOGOUT:
      return { ...state, logged_in_user: null };
    default:
      return state;
  }
}

标签: javascriptreactjsreact-native

解决方案


logs_in_user 是 LoginContainer 的一个属性吗?清楚这个变量的来源。在这种情况下,这是 AsyncStorage 而不是组件的道具。我怀疑logged_in_user 总是解析为false,这就是为什么注销永远不会起作用的原因。

        let { navigation, login } = this.props;
        let logged_in_user = await AsyncStorage.getItem('logged_in_user');

        if (!logged_in_user) {

            logged_in_user = await AsyncStorage.setItem('logged_in_user', !logged_in_user);
            login(true);
        }
        if (logged_in_user) {
            logged_in_user = await AsyncStorage.setItem('logged_in_user', !logged_in_user);
            navigation.navigate('SignedIn');
        }

推荐阅读