反应本机 Redux 与导航问题
React native Redux with Navigation issues
我最近开始使用 React Native 进行编程,并且刚刚开始使用导航,它们非常酷且功能强大。然而,作为初学者,我遇到了一些问题。我正在使用 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
状态为真,则呈现应用程序,否则呈现身份验证屏幕。问题是,当我通过登录页面使用 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 )
但是还是不行。再次,非常感谢
@内森贝莱特
根栈里,不应该有if-else语句的兄弟。您的第一个初始路由应该是 Authentication。我想你可以把它更新成这样。
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>
}
我希望这可以帮助您获得一些想法。
根据 React 导航文档,对于这种情况,您不应在放置堆栈导航器等的组件中执行任何条件。
更好的方法是先制作启动画面,这通常在每个应用程序中都有。
将其设置为初始路由,然后对要显示的页面进行逻辑计算,例如:
<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')
}
}
希望对您有所帮助。有疑问请随意
我最近开始使用 React Native 进行编程,并且刚刚开始使用导航,它们非常酷且功能强大。然而,作为初学者,我遇到了一些问题。我正在使用 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
状态为真,则呈现应用程序,否则呈现身份验证屏幕。问题是,当我通过登录页面使用 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 )
但是还是不行。再次,非常感谢
@内森贝莱特
根栈里,不应该有if-else语句的兄弟。您的第一个初始路由应该是 Authentication。我想你可以把它更新成这样。
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>
}
我希望这可以帮助您获得一些想法。
根据 React 导航文档,对于这种情况,您不应在放置堆栈导航器等的组件中执行任何条件。
更好的方法是先制作启动画面,这通常在每个应用程序中都有。
将其设置为初始路由,然后对要显示的页面进行逻辑计算,例如:
<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')
}
}
希望对您有所帮助。有疑问请随意