Javascript Navigation.navigate在react Navigation中不起作用
我正在创建一个应用程序,希望创建一个用户身份验证页面。我遵循了react导航网站的验证流页面上的教程,但现在每当我尝试从登录屏幕导航到注册页面时,我都会收到警告“无法从其他组件的函数体内部更新组件” 这是我的App.js:Javascript Navigation.navigate在react Navigation中不起作用,javascript,react-native,react-navigation,Javascript,React Native,React Navigation,我正在创建一个应用程序,希望创建一个用户身份验证页面。我遵循了react导航网站的验证流页面上的教程,但现在每当我尝试从登录屏幕导航到注册页面时,我都会收到警告“无法从其他组件的函数体内部更新组件” 这是我的App.js: import React, { useState } from 'react'; import { FlatList, } from 'react-native'; import { NavigationContainer, useNavigation } from
import React, { useState } from 'react';
import {
FlatList,
} from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import LoginScreen from "./Login";
import Home from "./Home";
import Signup from "./Signup";
import { AsyncStorage } from 'react-native'
export const COMPANY_NAME = "myCompany";
export const AuthContext = React.createContext();
const App: () => React$Node = () => {
const [state, dispatch] = React.useReducer(
(prevState, action) => {
switch (action.type) {
case 'RESTORE_TOKEN':
return {
...prevState,
userToken: action.token,
isLoading: false,
};
case 'SIGN_IN':
return {
...prevState,
isSignout: false,
userToken: action.token,
};
case 'SIGN_OUT':
return {
...prevState,
isSignout: true,
userToken: null,
};
}
},
{
isLoading: true,
isSignout: false,
userToken: null,
}
);
const authContext = React.useMemo(
() => ({
signIn: async data => {
// In a production app, we need to send some data (usually username, password) to server and get a token
// We will also need to handle errors if sign in failed
// After getting token, we need to persist the token using `AsyncStorage`
// In the example, we'll use a dummy token
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
},
signOut: () => dispatch({ type: 'SIGN_OUT' }),
signUp: async data => {
// In a production app, we need to send user data to server and get a token
// We will also need to handle errors if sign up failed
// After getting token, we need to persist the token using `AsyncStorage`
// In the example, we'll use a dummy token
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
},
}),
[]
);
React.useEffect(() => {
// Fetch the token from storage then navigate to our appropriate place
const bootstrapAsync = async () => {
let userToken;
try {
userToken = await AsyncStorage.getItem('userToken');
} catch (e) {
// Restoring token failed
}
// After restoring token, we may need to validate it in production apps
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
dispatch({ type: 'RESTORE_TOKEN', token: userToken });
};
bootstrapAsync();
}, []);
return (
<NavigationContainer>
<AuthContext.Provider value={{authContext}}>
<RootStack state={state} authContext={authContext}/>
</AuthContext.Provider>
</NavigationContainer>
);
};
function RootStack(props) {
const Stack = createStackNavigator();
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
{props.state.userToken == null ? (
<>
<Stack.Screen
name="Login"
component={LoginScreen}
/>
<Stack.Screen
name="Signup"
component={Signup}
/>
</>
) : (
<Stack.Screen
name="Home"
component={Home}
/>
)
}
</Stack.Navigator>
);
}
import React,{useState}来自“React”;
进口{
平面列表,
}从“反应本机”;
从'@react navigation/native'导入{NavigationContainer,useNavigation};
从'@react navigation/stack'导入{createStackNavigator};
从“/Login”导入登录筛选;
从“/Home”导入主页;
从“/Signup”导入注册;
从“react native”导入{AsyncStorage}
出口施工公司\u NAME=“myCompany”;
export const AuthContext=React.createContext();
常量应用程序:()=>React$Node=()=>{
const[state,dispatch]=React.useReducer(
(状态、动作)=>{
开关(动作类型){
案例“还原令牌”:
返回{
…国家,
userToken:action.token,
孤岛加载:false,
};
“签到”案例:
返回{
…国家,
isSignout:错,
userToken:action.token,
};
“注销”案例:
返回{
…国家,
是的,
userToken:null,
};
}
},
{
孤岛加载:是的,
isSignout:错,
userToken:null,
}
);
const authContext=React.useMoom(
() => ({
签名:异步数据=>{
//在生产应用程序中,我们需要向服务器发送一些数据(通常是用户名、密码)并获取令牌
//如果登录失败,我们还需要处理错误
//在获得令牌之后,我们需要使用'AsyncStorage'持久化令牌`
//在本例中,我们将使用虚拟令牌
分派({type:'SIGN_IN',token:'dummy auth token'});
},
签出:()=>dispatch({type:'SIGN_OUT'}),
注册:异步数据=>{
//在生产应用程序中,我们需要将用户数据发送到服务器并获取令牌
//如果注册失败,我们还需要处理错误
//在获得令牌之后,我们需要使用'AsyncStorage'持久化令牌`
//在本例中,我们将使用虚拟令牌
分派({type:'SIGN_IN',token:'dummy auth token'});
},
}),
[]
);
React.useffect(()=>{
//从存储器中取出令牌,然后导航到适当的位置
const bootstrapAsync=async()=>{
让userToken;
试一试{
userToken=await AsyncStorage.getItem('userToken');
}捕获(e){
//还原令牌失败
}
//还原令牌后,我们可能需要在生产应用程序中验证它
//这将切换到应用程序屏幕或身份验证屏幕,并进行此加载
//屏幕将被卸下并丢弃。
分派({type:'RESTORE_TOKEN',TOKEN:userToken});
};
bootstrapAsync();
}, []);
返回(
);
};
函数RootStack(props){
const Stack=createStackNavigator();
返回(
{props.state.userToken==null(
) : (
)
}
);
}
这是我的Login.js:
import {StatusBar, Text, TextInput, TouchableOpacity, View, Button, TouchableHighlight} from "react-native";
import styles, {MAIN_COLOR} from "./Styles";
import React, {useState} from "react";
import { COMPANY_NAME, AuthContext } from "./App";
import { useNavigation } from '@react-navigation/native'
import TouchableItem from "@react-navigation/stack/src/views/TouchableItem";
export default function LoginScreen({ navigation }) {
//Must be a child of AuthContext.Provider
const [username, setUsername] = useState();
const [password, setPassword] = useState();
const { authContext } = React.useContext(AuthContext);
console.log(AuthContext)
return (
<View style={styles.container}>
<StatusBar
backgroundColor={MAIN_COLOR}
/>
<Text style={styles.welcome}>Welcome to {COMPANY_NAME}!</Text>
<TextInput
style={styles.input}
placeholder='Username'
onChange={(text) => setUsername(text)}
/>
<TextInput
style={styles.input}
placeholder='Password'
secureTextEntry
onChange={(text) => setPassword(text)}
/>
<View style={styles.btnContainer}>
<TouchableOpacity style={styles.usrBtn}
onPress={() => navigation.navigate('Signup')}>
<Text style={styles.btnText}>Sign Up</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.usrBtn}
onPress={() => authContext.signIn({username, password})}>
<Text style={styles.btnText}>Login</Text>
</TouchableOpacity>
</View>
</View>
);
}
从“react native”导入{状态栏、文本、文本输入、TouchableOpacity、视图、按钮、TouchableHighlight};
导入样式,{MAIN_COLOR}来自“/styles”;
从“React”导入React,{useState};
从“/App”导入{COMPANY_NAME,AuthContext};
从'@react-navigation/native'导入{useNavigation}
从“@react navigation/stack/src/views/TouchableItem”导入TouchableItem;
导出默认函数LoginScreen({navigation}){
//必须是AuthContext.Provider的子级
const[username,setUsername]=useState();
const[password,setPassword]=useState();
const{authContext}=React.useContext(authContext);
console.log(AuthContext)
返回(
欢迎来到{公司名称}!
setUsername(文本)}
/>
设置密码(文本)}
/>
导航。导航('Signup')}>
注册
authContext.signIn({username,password}}>
登录
);
}
找到了答案。在我的Signup.js中,我有一个组件
<TouchableOpacity style={styles.usrBtn}
onPress={navigation.navigate('Login')}>
这需要改为
<TouchableOpacity style={styles.usrBtn}
onPress={() => navigation.navigate('Login')}>
navigation.navigate('Login')}>