1

我有一个应用程序,它的状态包含用户是否登录的信息。此状态被传递给 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 时应省略。但这似乎不起作用。我怎样才能使它工作?

4

0 回答 0