【问题标题】:How to update the state after refresh the App - React Native?刷新应用程序后如何更新状态 - React Native?
【发布时间】:2019-01-07 19:10:18
【问题描述】:

我正在开发一些带有简单欢迎屏幕的登录屏幕, 但是我在刷新应用程序时的状态存在一些问题,它仍然在初始屏幕中 [Indicator] 没有分开, 当我删除存储密钥时,我需要将状态加载到另一个状态,但它不适用于我:L,你能帮我解决这个问题吗?

我的屏幕

首次登录后

刷新应用时[双 R 键] - 我需要将我移至登录表单

这是我的代码

/Login.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>
    );
  }
}

【问题讨论】:

    标签: javascript android reactjs react-native redux


    【解决方案1】:

    问题出在你的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 中使用。

    问题是,当您在注销后导航到主屏幕时,您正在检查 AsyncStorage 中的 username,但如果它未定义,您将 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");
          }
        });
      }
    

    您应该能够看到登录屏幕而不是微调器。希望这会有所帮助。

    【讨论】:

    • 谢谢,但我在登录前看到的第一件事是登录屏幕而不是微调器
    猜你喜欢
    • 2017-11-09
    • 2019-09-17
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多