我如何在本机 class 中使用渲染元素(如图标)的函数?

How do i use functions that render elements (like icons) in a react native class?

我目前正在尝试使用 React Native。起初我将屏幕导出为函数,但后来将它们重写为 类 因为它更容易实现 Redux。

我的 类 现在看起来像这样:

import React from "react";
import { connect } from "react-redux";
import { StyleSheet, View, TouchableWithoutFeedback } from "react-native";
import { Input, Divider, Text, Button } from "@ui-kitten/components";
import { updateAuthStatus } from "../../store/actions/authentication";
import { signIn } from "../../services/authentication.service";
import { save } from "../../services/secure.store.service";
import Spinner from "react-native-loading-spinner-overlay";
import Ionicons from "react-native-vector-icons/Ionicons";

class SignInScreen extends React.Component {
  constructor() {
    super();
    this.state = {
      spinner: false,
      identifier: "",
      password: "",
      secureTextEntry: true,
    };
  }

  componentDidMount() {}

  toggleSecureEntry = () => {
    this.setState({ secureTextEntry: !this.state.secureTextEntry });
  };

  changeSpinnerState = (state) => {
    this.setState({ spinner: state });
  };

  setIdentifier = (text) => {
    this.setState({ identifier: text });
  };

  setPassword = (text) => {
    this.setState({ password: text });
  };

  googleIcon = () => {
    return <Ionicons name="logo-google" size={18} />;
  };

  eyeIcon = () => {
    return (
      <TouchableWithoutFeedback onPress={this.toggleSecureEntry()}>
        <Ionicons
          name={this.state.secureTextEntry ? "eye-outline" : "eye-off-outline"}
          size={18}
        />
      </TouchableWithoutFeedback>
    );
  };

  render() {
    return (
      <View style={styles.signIn_screen}>
        <Spinner
          visible={this.state.spinner}
          textContent={"Anmeldung läuft..."}
          textStyle={styles.spinnerTextStyle}
        />
        <View style={styles.row}>
          <Text category="h5">Anmelden</Text>
        </View>
        <View style={styles.form}>
          <Input
            style={styles.input_username}
            value={this.state.identifier}
            size="large"
            label="Benutzername/E-Mail"
            placeholder="Benutzername oder E-Mail"
            onChangeText={(text) => {
              this.setIdentifier(text);
            }}
          />
          <Input
            style={styles.input_password}
            value={this.state.password}
            size="large"
            label="Passwort"
            placeholder="Passwort eingeben"
            accessoryRight={this.eyeIcon()}
            secureTextEntry={this.state.secureTextEntry}
            onChangeText={(text) => {
              this.setPassword(text);
            }}
          />
        </View>
        <Text style={styles.text_password_reset}>Passwort vergessen?</Text>
        <View style={styles.form}>
          <Button
            style={styles.button_signIn}
            onPress={() => {
              this.changeSpinnerState(false);
              signIn(identifier, password).then((response) => {
                if (response.status) {
                  if (response.status === 200) {
                    save(
                      "credentials",
                      JSON.stringify({
                        identifier: identifier,
                        password: response.json.token,
                      })
                    ).then((stored) => {
                      if (stored) {
                        this.changeSpinnerState(false);
                        navigation.navigate("Home");
                      }
                    });
                  }
                }
              });
            }}
          >
            Anmelden
          </Button>
          <Text
            style={styles.text_not_registered}
            onPress={() => navigation.navigate("SignUp")}
          >
            Noch keinen Account? Melde registriere dich hier.
          </Text>
          <View style={styles.row}>
            <Divider style={styles.divider} />
            <View style={styles.view_social_login}>
              <Text style={{ color: "#a3a3a3" }}>oder</Text>
            </View>
            <Divider style={styles.divider} />
          </View>
          <Button
            style={styles.button_google}
            status="basic"
            accessoryLeft={this.googleIcon()}
            appearance="ghost"
          >
            Mit Google anmelden
          </Button>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  spinnerTextStyle: {
    color: "#FFF",
  },
  signIn_screen: {
    flex: 1,
    padding: 16,
    backgroundColor: "#fff",
    justifyContent: "center",
  },
  form: {
    alignItems: "center",
  },
  input_username: {
    marginBottom: 16,
  },
  input_password: {
    marginBottom: 16,
  },
  button_signIn: {
    alignSelf: "stretch",
    marginBottom: 16,
  },
  divider: {
    width: 100,
    height: 1,
    backgroundColor: "#e0e0e0",
  },
  button_google: {
    color: "#8F9BB3",
    backgroundColor: "transparent",
    borderColor: "transparent",
  },
  row: {
    marginTop: 32,
    marginBottom: 32,
    flexDirection: "row",
    alignItems: "center",
  },
  text_not_registered: {
    fontSize: 12,
    color: "#8c8262",
  },
  text_password_reset: {
    fontSize: 12,
    color: "#8c8262",
    marginBottom: 32,
  },
  view_social_login: {
    width: 50,
    height: 1,
    alignItems: "center",
    justifyContent: "center",
  },
});

const mapStateToProps = (state) => {
  return {
    authenticated: state.reducer.authenticated,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    updateAuth: (status) => dispatch(updateAuthStatus(status)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(SignInScreen);

现在唯一的问题是我的图标 googleIcon 和 eyeIcon 不再显示,我不知道我做错了什么。

当我将屏幕导出为函数时,我可以只使用返回图标的常量函数。

这样做会为我抛出这个错误:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `FalsyFC`.

关于如何解决这个问题有什么建议吗?

这是你的问题:

eyeIcon = () => {
    return (
      <TouchableWithoutFeedback onPress={this.toggleSecureEntry()}> <------ HERE
        <Ionicons
          name={this.state.secureTextEntry ? "eye-outline" : "eye-off-outline"}
          size={18}
        />
      </TouchableWithoutFeedback>
    );
  };

通过这样声明您的函数,您将在每次组件呈现时调用它。您应该始终将 REFERENCE 传递给函数,例如 () => this.toggleSecureEntry()this.toggleSecureEntry。我会更深入地解释一下 .