如何在 React-Native 中的状态更改后重新渲染?

时间:2021-03-29 13:59:57

标签: react-native

我正在开发 React Native 应用程序,在开始之前必须是覆盖视图。就像“欢迎屏幕”。在覆盖视图中阅读内容后,按确定。

setState 不起作用。抛出错误 TypeError: _this.setState is not a function

我会尝试像这样使用 setState:

removeElement = () => {
  //this.state.loadingScreen = false;
  this.setState({
    loadingScreen: false
  })
  console.log(`Staten arvo nyt: ` + this.state.loadingScreen);

当我使用 setState 时,它​​应该重新渲染组件,但我不知道它不起作用的原因是什么。我可以更改状态 this.state.loadingScreen = false;,但它不会重新呈现。 forceUpdate() 也不起作用。

问题:如何再次渲染组件以摆脱叠加视图?

我的代码:

import React, { useState, setState, Component } from "react";
import { Text, View, StyleSheet, TextInput, Button, Alert, TouchableOpacity} from "react-native";
import AsyncStorage from '@react-native-community/async-storage';

export default function StartPage({ navigation }) {

  state = {  
    loadingScreen: true,
  }

  let userInput = "";
  let userInputName = "";

  readUserInput = (text) => {
    userInput = text
  }
  readUserInputName = (text) => {
    userInputName = text
  }
  checkUserInput = () => {
  if(userInput.length < 1 && userInputName.length < 1){
      Alert.alert("Tarkista rekisterinumero ja nimi")
    }
    else{
      storeData = async () => {
        try{
            AsyncStorage.setItem("RegistrationNumber", userInput);
            AsyncStorage.setItem("UserName", userInputName);           
        }
        catch(e){
            console.log(e);
        }
      }
      storeData();
      navigation.navigate("GeneralInspection")
    }
  }
  renderElement = () =>{
    if(this.state.loadingScreen == true)
       return <View style={styles.fullScreen}>
       <TouchableOpacity style={styles.button} onPress={this.removeElement}>
          <Text style={{fontSize:20}}>Change state to false</Text>
        </TouchableOpacity>
    </View>;;
       
    return null;
 }

 removeElement = () => {
  this.state.loadingScreen = false
 }

 setTimeout(
  function() {
      
  }
  .bind(this),
  1000
);

  return (
    <View style={styles.view}>
        { this.renderElement() }
    <Text style={styles.text}>Tiedot</Text>
    <TextInput
      style={styles.inputStyle}
      placeholder="Nimi"
      onChangeText={this.readUserInputName}
      autoCapitalize="words"
    />
    <TextInput
      style={styles.inputStyle}
      placeholder="ABC-123"
      onChangeText={this.readUserInput}
      autoCapitalize="characters"
    />
    <TouchableOpacity style={styles.button} onPress={this.checkUserInput}>
      <Text style={{fontSize:20}}>Aloita</Text>
    </TouchableOpacity>
  </View>
  );
}



const styles = StyleSheet.create({
  view: {
    height: "100%",
    width: "100%",
    justifyContent: "center",
    alignItems: "center",
  },
  text: {
    fontSize: 40,
    fontWeight: "bold",
    padding:10,
    fontStyle:"italic"
  },
  inputStyle: {
    height:50,
    borderColor:"black",
    borderWidth:1,
    width:"50%",
    marginBottom:15,
    textAlign:"center",
    fontSize: 20,
    borderRadius:5,
  },
  button: {
    backgroundColor:"#007bff",
    borderRadius:5,
    padding:8,
    width:"50%",
    height: 60,
    alignItems:"center",
    justifyContent: "center",
  },
  fullScreen: {
    height: "100%",
    width: "100%",
    zIndex: 100,
    position: "absolute",
    backgroundColor: "red",
  }
});

1 个答案:

答案 0 :(得分:0)

您在 OP 中使用了一个功能组件,这需要您使用 useState Hooks 来管理您的状态。 如果您使用的是类组件,则可以使用 setState 方法。在这两种情况下,React 都会处理重新渲染的部分。

如果使用基于类的方法,像 this.state.loadingScreen = false 这样的改变状态不会触发 UI 的重新渲染。您将不得不改用 setState 方法。

基于类的方法

import React from "react";
import { Text, View, StyleSheet, TextInput, Alert, TouchableOpacity } from "react-native";
import AsyncStorage from '@react-native-community/async-storage';

export default class StartPage extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      loadingScreen: true,
      userInput: "",
      userInputName: ""
    };
  }

  readUserInput = (text) => {
    this.setState({
      userInput: text
    });
  }

  readUserInputName = (text) => {
    this.setState({
      userInputName: text
    });
  }

  storeData = async () => {
    const { userInput, userInputName } = this.state;
    try {
      AsyncStorage.setItem("RegistrationNumber", userInput);
      AsyncStorage.setItem("UserName", userInputName);
      this.props.navigation.navigate("GeneralInspection");
    }
    catch (e) {
      console.log(e);
    }
  }

  checkUserInput = () => {
    const { userInput, userInputName } = this.state;
    if (userInput.length < 1 && userInputName.length < 1)
      Alert.alert("Tarkista rekisterinumero ja nimi");
    else
      this.storeData();
  }

  renderElement = () => {
    if (this.state.loadingScreen)
      return (
        <View style={styles.fullScreen}>
          <TouchableOpacity style={styles.button} onPress={this.removeElement}>
            <Text style={{ fontSize: 20 }}>Change state to false</Text>
          </TouchableOpacity>
        </View>
      );
    return null;
  }

  removeElement = () => {
    this.setState({
      loadingScreen: false
    });
  }

  render() {
    return (
      <View style={styles.view} >
        { this.renderElement()}
        < Text style={styles.text} > Tiedot</Text>
        <TextInput
          style={styles.inputStyle}
          placeholder="Nimi"
          value={this.state.userInputName}
          onChangeText={this.readUserInputName}
          autoCapitalize="words"
        />
        <TextInput
          style={styles.inputStyle}
          placeholder="ABC-123"
          value={this.state.userInput}
          onChangeText={this.readUserInput}
          autoCapitalize="characters"
        />
        <TouchableOpacity style={styles.button} onPress={this.checkUserInput}>
          <Text style={{ fontSize: 20 }}>Aloita</Text>
        </TouchableOpacity>
      </View >
    );
  }
}

基于功能组件的方法

import React, { useState } from "react";
import { Text, View, StyleSheet, TextInput, Alert, TouchableOpacity } from "react-native";
import AsyncStorage from '@react-native-community/async-storage';

export default function StartPage({ navigation }) {

  const [loadingScreen, setLoadingScreen] = useState(true);
  const [userInput, setUserInput] = useState('');
  const [userInputName, setUserInputName] = useState('');

  const readUserInput = (text) => {
    setUserInput(text);
  };

  const readUserInputName = (text) => {
    setUserInputName(text);
  };

  const storeData = async () => {
    try {
      AsyncStorage.setItem("RegistrationNumber", userInput);
      AsyncStorage.setItem("UserName", userInputName);
      navigation.navigate("GeneralInspection");
    }
    catch (e) {
      console.log(e);
    }
  };

  const checkUserInput = () => {
    if (userInput.length < 1 && userInputName.length < 1)
      Alert.alert("Tarkista rekisterinumero ja nimi");
    else
      storeData();
  };

  const renderElement = () => {
    if (loadingScreen)
      return (
        <View style={styles.fullScreen}>
          <TouchableOpacity style={styles.button} onPress={removeElement}>
            <Text style={{ fontSize: 20 }}>Change state to false</Text>
          </TouchableOpacity>
        </View>
      );
    return null;
  };

  const removeElement = () => {
    setLoadingScreen(false);
  };

  return (
    <View style={styles.view} >
      {renderElement()}
      < Text style={styles.text} > Tiedot</Text>
      <TextInput
        style={styles.inputStyle}
        placeholder="Nimi"
        value={userInputName}
        onChangeText={readUserInputName}
        autoCapitalize="words"
      />
      <TextInput
        style={styles.inputStyle}
        placeholder="ABC-123"
        value={userInput}
        onChangeText={readUserInput}
        autoCapitalize="characters"
      />
      <TouchableOpacity style={styles.button} onPress={checkUserInput}>
        <Text style={{ fontSize: 20 }}>Aloita</Text>
      </TouchableOpacity>
    </View >
  );
}