我有一个应用程序,它的状态包含用户是否登录的信息。此状态被传递给 Context Provider:
应用程序.native.js
import React, { Component } from "react";
import Orientation, { orientation } from "react-native-orientation";
import Navigator from "./navigation/Navigator";
import { createContext } from 'react';
export const LoginContext = createContext({
isLoggedIn: false,
login: () => {},
logout: () => {}
});
export default class App extends Component {
constructor(props) {
super(props);
this.login = () => {
this.setState(state => ({
isLoggedIn: true
}));
console.log("Logged in!");
};
this.logout = () => {
this.setState(state => ({
isLoggedIn: false
}));
console.log("Logged out!");
};
this.state = {
isLoggedIn: false,
login: this.login,
logout: this.logout
};
}
componentDidMount = () => {
Orientation.lockToPortrait();
};
render() {
return <LoginContext.Provider value={this.state}><Navigator /></LoginContext.Provider>;
}
}
在(几乎)应用程序的每个屏幕中,我想在标题中显示一个图标,例如:
SearchScreen.js
import styles from './styles';
import React, { Component } from 'react';
import { Text, View,AsyncStorage } from 'react-native';
import { Button } from 'react-native-elements';
import LoginIcon from '../../components/LoginIcon'
import { StatusBar } from 'react-native'
class SearchScreen extends Component {
static navigationOptions = ({ navigation }) => ({
headerTitle: "Suchen",
headerRight: <LoginIcon navigation={navigation} />
});
render() {
return (
<View style={styles.container}>
<StatusBar barStyle = "dark-content" hidden = {false} backgroundColor = "#338A3E" />
<Text>This is the SearchScreen.</Text>
</View>
);
}
}
export default SearchScreen;
该图标应显示登录或注销图像,具体取决于应用程序的状态。我尝试通过使用上下文消费者来做到这一点:
登录图标.js
import styles from "./styles";
import React, { Component } from "react";
import { View, AsyncStorage } from "react-native";
import { Icon } from "react-native-elements";
import AntIcon from "react-native-vector-icons/AntDesign";
import {LoginContext} from "../../App.native.js";
const LoginIcon = ({navigation}) => {
return (
<LoginContext.Consumer>
{({isLoggedIn, login, logout}) => {
return (isLoggedIn ?
<Icon
name="logout"
type='material-community'
containerStyle={styles.icon}
color="white"
onPress={logout}
/>
:
<Icon
name="login"
type='material-community'
containerStyle={styles.icon}
color="white"
onPress={navigation.navigate("Login")}
/> );
}
}
</LoginContext.Consumer>
);
}
export default LoginIcon;
现在,当我登录时(通过此处未显示的 LoginScreen),状态按预期更改(isLoggedIn = true),并且 SearchScreen 的 Heder 中的图标显示正确的“注销”按钮。这太棒了!
但是当我单击此按钮时,出现两个错误:
1:警告:在现有状态转换期间无法更新(例如在“渲染”内)。渲染方法应该是 props 和 state 的纯函数。 这对我来说是个谜,我知道我这里有一个设计缺陷,但不知道如何解决它,因为......好吧,基本上所有事情都发生在渲染函数中?
2)道具类型失败:提供给“图标”的“布尔”类型的无效道具“onPress”,预期为“功能”。在 Icon (at withTheme.js:24) in Themed.Icon (at LoginIcon.js:22) in LoginIcon (at SearchScreen.js:12) 据我所知,将道具传递给函数组件是可能的,但是 this.props在组件内部调用 prop 时应省略。但这似乎不起作用。我怎样才能使它工作?