javascript - 刷新应用程序后如何更新状态 - React Native?
问题描述
我正在使用简单的欢迎屏幕开发一些登录屏幕,但是在刷新应用程序时状态存在一些问题,它仍然在启动屏幕中 [ Indicator ] 没有分开,我需要在删除存储密钥时更新状态加载到另一个状态,但它不适用于我:L,你能帮我解决这个问题吗?
我的屏幕
首次登录后
刷新应用程序时 [双 R 键] - 我需要将我移至登录表单
这是我的代码
/登录.js
import React, { Component } from "react";
import {
StyleSheet,
View,
StatusBar,
Text,
TextInput,
TouchableOpacity,
ActivityIndicator,
AsyncStorage
} from "react-native";
export default class Login extends Component {
constructor() {
super();
this.state = {
username: "",
password: "",
isLoad: false
};
}
async componentWillMount() {
await AsyncStorage.getItem("@myApp:username").then(username => {
if (!username || username === "") {
this.setState({
isLoad: true
});
} else {
this.setState({ username: username });
this.props.navigation.navigate("Home");
}
});
}
_onLogin = () => {
let { username, password } = this.state;
if (username !== "" && password !== "") {
AsyncStorage.setItem("@myApp:username", this.state.username).then(
username => {
this.setState({ username: username });
}
);
this.props.navigation.navigate("Home");
}
};
render() {
if (!this.state.isLoad) {
return (
<View
style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
>
<ActivityIndicator size="large" color="red" />
</View>
);
} else {
return (
<View style={styles.container}>
<StatusBar backgroundColor="#333" barStyle="light-content" />
<Text style={{ fontSize: 28, margin: 10 }}>Login</Text>
<TextInput
placeholder="Username"
onChangeText={username => {
this.setState({ username: username });
}}
value={this.state.username}
autoCorrect={false}
returnKeyType="next"
style={{
padding: 10,
margin: 15,
borderBottomColor: "#333",
borderBottomWidth: 1,
width: "80%"
}}
editable={true}
/>
<TextInput
placeholder="Password"
onChangeText={password => {
this.setState({ password: password });
}}
secureTextEntry={true}
value={this.state.password}
autoCorrect={false}
returnKeyType="next"
style={{
padding: 10,
margin: 15,
borderBottomColor: "#333",
borderBottomWidth: 1,
width: "80%"
}}
editable={true}
/>
<TouchableOpacity
style={{
margin: 20,
padding: 10,
width: "70%",
backgroundColor: "#1a73e8"
}}
onPress={this._onLogin}
>
<Text style={{ color: "#FFF", textAlign: "center", fontSize: 18 }}>
Log In
</Text>
</TouchableOpacity>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fff"
}
});
./Home.js
import React, { Component } from "react";
import {
StyleSheet,
View,
ImageBackground,
Alert,
Text,
AsyncStorage,
TouchableOpacity
} from "react-native";
export default class Home extends Component {
constructor() {
super();
this.state = {
name: ""
};
}
async componentDidMount() {
try {
const storedValue = await AsyncStorage.getItem("@myApp:username");
this.setState({ name: storedValue });
if (storedValue == null) {
this.props.navigation.navigate("Login");
}
} catch (error) {
Alert.alert("Error", "There was an error.");
}
}
_onLogout = () => {
AsyncStorage.removeItem("@myApp:username").then(() => {
this.setState({ name: "" });
});
this.props.navigation.navigate("Login");
};
render() {
return (
<View style={styles.container}>
<ImageBackground
source={require("./assets/bg1.jpg")}
style={{
flex: 1,
width: "100%",
height: "100%"
}}
>
<View
style={{
backgroundColor: "rgba(0,0,0,0)",
flex: 1,
justifyContent: "center"
}}
>
<Text
style={{
alignSelf: "center",
backgroundColor: "#000fff",
padding: 10,
color: "#fff"
}}
>
{`Hello, ${this.state.name} `}
</Text>
<TouchableOpacity
style={{
margin: 20,
padding: 10,
width: "50%",
backgroundColor: "#1a73e8",
justifyContent: "center",
alignSelf: "center"
}}
onPress={this._onLogout}
>
<Text
style={{ color: "#FFF", textAlign: "center", fontSize: 18 }}
>
Log out?
</Text>
</TouchableOpacity>
</View>
</ImageBackground>
</View>
);
}
}
解决方案
问题出在你的componentWillMount
async componentWillMount() {
await AsyncStorage.getItem("@myApp:username").then(username => {
if (!username || username === "") {
this.setState({
isLoad: true // This is the issue
});
} else {
this.setState({ username: username });
this.props.navigation.navigate("Home");
}
});
}
首先,您应该避免使用componentWillMount
和使用componentDidMount
,因为前者现在已被弃用,并且不建议在较新版本的 react 中使用。
问题是,当您在注销后导航到主屏幕时,您正在检查,username
但AsyncStorage
如果它未定义,您将isLoad
状态设置为 true,这会呈现ActivityIndicator
. 如果有的话,你应该isLoad
在承诺解决之前做。如果您将代码替换为:
componentDidMount() {
this.setState({ isLoad: true });
AsyncStorage.getItem("@myApp:username").then(username => {
if (!username || username === "") {
this.setState({
isLoad: false // change this to False
});
} else {
this.setState({ username: username, isLoad: false });
this.props.navigation.navigate("Home");
}
});
}
您应该能够看到登录屏幕而不是微调器。希望这可以帮助。
推荐阅读
- c# - 使用 OptGroup 创建 DropDownList
- c - 链接列表和 pthread 的问题
- docker - 如何使`docker-compose up $container_name`不仅附加到$container_name,而且附加到它所依赖的所有容器?
- windows - 用于 Ping 计算机的 PowerShell 脚本有效但出现错误
- r - 使用 Mclust 进行聚类会导致空聚类
- python - VS Code 上的 Anaconda 环境
- python - 当列具有重复值且值来自函数时,批量替换熊猫数据框中的值
- matlab - 计算从正态分布创建的时间序列的自相关
- c++ - 阅读更多 midi 数据
- python - 是否可以生成随机字符串并将其用作关系数据库上的 ID