对本机Redux遇到导航问题

时间:2020-05-16 00:55:57

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

我最近开始在React Native中进行编程,并且刚接触了Navigations,它们非常酷并且功能强大。但是,作为一个初学者,我遇到了一些问题。我正在使用Redux来管理状态,并且我有一个导航堆栈,该堆栈仅应在登录状态为活动状态时呈现。这是代码的一小段。

const RootStackScreen = () => (
  <RootStack.Navigator headerMode="none">
    {initialState.loggedIn ? (
      <RootStack.Screen name="Application" component={TabScreen} />
    ) : (
      <RootStack.Screen name="Authentication" component={AuthStackScreen} />
    )}
  </RootStack.Navigator>
);

如您在这里看到的,我的RootStack中有两个屏幕,我的身份验证屏幕,然后是我的主应用程序屏幕。我只是想说嘿,如果loggedIn状态为true,则渲染应用程序,否则渲染身份验证屏幕。问题是,当我通过登录页面更改redux的状态时,它会更新,但不会更改页面。为了方便起见,我还附加了我的redux initialState和reducer

const initialState = {
  action: "",
  loggedIn: false,
  username: null,
  isLoading: false,
  failedLogin: "",
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "USER_LOGIN_GOOD":
      return { loggedIn: true };
    case "USER_LOGIN_FAIL":
      return { failedLogin: "Login Failed, Please try again" };
    default:
      return state;
  }
};

我尝试说的是initialState.loggedIn以及loggedIn,但是由于某种原因,当通过另一个页面中的redux更新值时,它不会更新值。我已经检查过,只需打印新值就可以确保值正在更新,所以我知道更新值不是问题,而只有RootStack可以感知更新。

非常感谢!任何帮助都将是有用的,因为我为此一直在努力!!

更新:我通过调用Dispatch来从我的登录页面设置状态

function mapDispatchToProps(dispatch) {
  return {
    logInSuccess: () =>
      dispatch({
        type: "USER_LOGIN_GOOD",
      }),
    logInFailed: () =>
      dispatch({
        type: "USER_LOGIN_FAIL",
      }),
  };
}

我也尝试过将initialState这样传递到RootStack中

const RootStackScreen = (initialState) => ( CONTENT HERE )

但是它仍然不起作用。再次,非常感谢

2 个答案:

答案 0 :(得分:1)

对于这种情况,根据React Navigation文档,您不应在放置堆栈导航器等的组件中执行任何条件。

更好的方法是先制作启动屏幕,通常在每个应用程序中都存在。

使其成为初始路线,然后对要显示的页面进行逻辑计算,例如:

<Stack.Navigator
          initialRouteName="SplashScreen"
          >
          <Stack.Screen name="Login" component={LoginScreen} />
          <Stack.Screen name="SplashScreen" component={SplashScreen} />
          <Stack.Screen name="Home" component={Home} />
        </Stack.Navigator>

因此,这里的Splashscreen是初始路线,在Splashscreen中,您喜欢:

class SplashScreen extends .. {

...
componentDidMount(){
isLoggedIn?this.props.navigation.navigate('Home'):this.props.navigation.navigate('Login')
}

}

希望有帮助。毫无疑问

答案 1 :(得分:0)

@内森·贝莱特

在根堆栈中,您不应有if-else语句兄弟。您的第一个初始路由应为身份验证。我认为您可以将其更新为这样。

const RootStackScreen = () => (
  <RootStack.Navigator headerMode="none" initialRouteName="Authentication">
      <RootStack.Screen name="Application" component={TabScreen} />
      <RootStack.Screen name="Authentication" component={AuthStackScreen} />
    )}
  </RootStack.Navigator>
);

然后在文件 AuthStackScreen.js 中处理逻辑,以检查用户是否已经登录。这是示例代码:

import {useDispatch, useSelector, useStore} from 'react-redux'

export const SignInScreen = ({navigation}: SignInProps): ReactElement => {
  const dispatch = useDispatch()
  const appState = useStore().getState()
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    if (appState.loggedIn) {
      navigation.replace('Application')
    }

    setLoading(false)
  }, [])

  if (loading) return <LoadingScreen />

  return <YOUR_COMPONENT>

}

我希望这对您有所帮助。