React native 使用React本机导航发送redux时出现注销错误

React native 使用React本机导航发送redux时出现注销错误,react-native,redux,react-navigation,logout,dispatch,React Native,Redux,React Navigation,Logout,Dispatch,在我的React Native应用程序中,实际上我需要使用导航和redux实现一个简单的注销,但是当我从我的主页(按注销按钮时)发送注销操作时,我出现了一个错误,因为在主页中,我呈现了当前用户,而此时不存在 我需要调度注销(删除当前用户),然后导航到登录页面而不重新呈现主页,或者了解在呈现之前如何装载implement Component。。。。 怎么做? 我的简历代码: (登录有效,我不输入登录代码) App.tsx import React, {useState} from 'react'

在我的React Native应用程序中,实际上我需要使用导航和redux实现一个简单的注销,但是当我从我的主页(按注销按钮时)发送注销操作时,我出现了一个错误,因为在主页中,我呈现了当前用户,而此时不存在

我需要调度注销(删除当前用户),然后导航到登录页面而不重新呈现主页,或者了解在呈现之前如何装载implement Component。。。。 怎么做?

我的简历代码: (登录有效,我不输入登录代码)

App.tsx

import React, {useState} from 'react';
import { NavigationContainer, StackActions } from '@react-navigation/native';
//... many imports

const store = createStore(rootReducer);

export default class App extends React.Component {
   constructor(props) {
    super(props);
    this.state = { loading: true };
   }

async componentDidMount() {
  //... some code
}

render(){
   if (this.state.loading) {
     return (
       <Root>
         <AppLoading />
       </Root>
    );
   }
   else {
     return (
       <Provider store={store}>
        <Root>
          <NavigationContainer>
            <Navigator/>
          </NavigationContainer>
        </Root>
       </Provider>          
     );
   }
  }
}
import React from 'react'
import { createStackNavigator } from '@react-navigation/stack'
import {connect} from 'react-redux'
import Login from '../Views/Login'
import Home from '../Views/Home'

const Stack = createStackNavigator();

const Navigator= (props) =>{
   const {users} = props;
   return (
        <Stack.Navigator>
            {console.log('Navigator here, '+users.current)}
            {users.current ===null ? 
                (<>    
                    <Stack.Screen name="Login" component={Login}  options={{headerShown:false}}/>
                </>)
            :   (<>    
                    <Stack.Screen name="Home" component={Home} options={{headerShown:false}}/>
                </>)
            }
        </Stack.Navigator>
    );
 }

const mapStateToProps=(state)=>{
   const {users} = state;
   return {users};
}

export default connect(mapStateToProps)(Navigator);
const Initial_State={
   current:null
}

export function UserReducer(state=Initial_State, action:any){
   switch (action.type){
    case 'ADD_USER':
        return{
            ...state,
            current: action.user
        };
    case 'DELETE_USER':
        return{
            ...state,
            current: null
        };
    default:
        return state;
   }
}
AuthService.tsx(这里是调度)


在您目前的情况下,您可以通过更改

  <Text>Hi {users.current.id}</Text>

您的
Home
组件希望从状态中选择一个用户对象。注意,您应该只选择所需的特定对象,
state.users.current
,而不是选择
state.users
,然后查看
users.current

除非有用户,否则我们不希望
Home
呈现,因此我们可以
useffect
有条件地导航离开页面。这意味着我们实际上不需要等待注销,因为只要没有用户,导航就会自动进行。该操作被调度-->redux状态更改-->currentUser道具更改-->效果运行-->导航发生

const Home = (props) => {
  const { navigation, currentUser } = props;

  function Logout(id) {
    // no async/await here
    // navigation is triggered when currentUser updates
    Auth.LogoutUser(id, props);
  }

  useEffect(() => {
    if (!currentUser) {
      navigation.navigate("Login");
    }
  }, [currentUser, navigation]);

  if (!currentUser) {
    // should only end up here momentarily while navigation is taking place
    return null;
  }
  
  return (
    <Container>
      <Content>
        <View style={Styles.content}>
          <Text>Hi {currentUser.id}</Text>
          <Button onPress={() => Logout(currentUser.id)}>
            <Icon name="exit" />
          </Button>
        </View>
      </Content>
    </Container>
  );
};

const mapStateToProps = (state) => {
  return {
    currentUser: state.users.current
  };
};

export default connect(mapStateToProps)(Home);
const Home=(道具)=>{
const{navigation,currentUser}=props;
功能注销(id){
//这里没有异步/等待
//当前用户更新时会触发导航
授权登录用户(id、道具);
}
useffect(()=>{
如果(!currentUser){
导航。导航(“登录”);
}
},[currentUser,navigation]);
如果(!currentUser){
//应该只在导航过程中暂时停在这里
返回null;
}
返回(
你好{currentUser.id}
注销(currentUser.id)}>
);
};
常量mapStateToProps=(状态)=>{
返回{
currentUser:state.users.current
};
};
导出默认连接(MapStateTops)(主);

state=undefined
这不是正确的重复。是的@Linda,在某些情况下不是,这就是为什么我提到可以根据我们的用例将其重置为某些初始状态或应用程序状态。您需要
返回状态的新值。您不能执行
state=
。在这种情况下,我们并没有改变状态,我们只是给state(local)变量赋值,并将相同的变量传递给app reducer。因此,评估者将返回一个新状态。因此没有违反redux原则(状态突变)。-不起作用,错误:TypeError:null不是对象(评估'currentUser.id')此错误位于:in Home(由ConnectFunction创建)useEffect只在第一次在Home中调用,当我按logout时它没有被调用(我知道,因为我在函数中放了一个console.log()),第一个错误没有意义,因为它说
currentUser
null
,但是如果(!currentUser){return null;},我们会调用
在我们尝试访问
currentUser.id
之前。是的,你是对的,我忘记了这个条件。现在它起作用了。谢谢:)
  <Text>Hi {users.current.id}</Text>
<Text>Hi {users?.current?.id}</Text>
import { combineReducers } from 'redux';
import UsersReducer from './UsersReducer';

  const appReducer = combineReducers({
      users: UsersReducer,
     // other Reducers if there is any.
    });

 const rootReducer = (state, action) => {
   // When logout action is dispatched  reset the action.
   if (action.type === 'USER_LOG_OUT') {
     state = undefined; // or to initial state if {} you want any data without session 
    }
    return appReducer(state, action);
   };

export default rootReducer;
const Home = (props) => {
  const { navigation, currentUser } = props;

  function Logout(id) {
    // no async/await here
    // navigation is triggered when currentUser updates
    Auth.LogoutUser(id, props);
  }

  useEffect(() => {
    if (!currentUser) {
      navigation.navigate("Login");
    }
  }, [currentUser, navigation]);

  if (!currentUser) {
    // should only end up here momentarily while navigation is taking place
    return null;
  }
  
  return (
    <Container>
      <Content>
        <View style={Styles.content}>
          <Text>Hi {currentUser.id}</Text>
          <Button onPress={() => Logout(currentUser.id)}>
            <Icon name="exit" />
          </Button>
        </View>
      </Content>
    </Container>
  );
};

const mapStateToProps = (state) => {
  return {
    currentUser: state.users.current
  };
};

export default connect(mapStateToProps)(Home);