我如何在本机 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
。我会更深入地解释一下 .
我目前正在尝试使用 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
。我会更深入地解释一下