【问题标题】:What am I doing wrong with my render method that I'm receiving "Invariant Violation" error?我收到“不变违规”错误的渲染方法做错了什么?
【发布时间】:2019-11-14 15:45:06
【问题描述】:

我正在开始一个新的 React Native 项目,我使用了“expo init”并选择了一个空白托管项目作为我的模板。我有几个来自不同项目的屏幕和组件,我想将它们复制到我的新项目中。我收到以下错误:

Invariant Violation:元素类型无效:应为字符串(对于 内置组件)或类/函数(用于复合组件) 但得到:未定义。您可能忘记从 定义它的文件,或者您可能混淆了默认值和命名 进口。

查看CreateAccountForm的渲染方法。

我不知道发生了什么。我很确定我的所有设置都与我在第一个项目中所做的完全一样,这一切都很好。我正在使用 React Navigation,我的新项目将“HomeScreen”渲染为“initialRouteName”。但是,每当我尝试将初始路由设置为“CreateNewAccountScreen”时,都会收到上述错误。

我已经对其进行了测试,只要不尝试渲染嵌套在其中的“CreateAccountForm”组件,“CreateNewAccountScreen”就会将属性渲染为我的初始路由。将<CreateAccountForm> 组件替换为简单的<Text>Hi!<Text> 后,它与<Advertisement> 组件一起毫无问题地渲染了屏幕。

主屏幕:

import React from 'react';
import { StyleSheet, Image, Button, View } from 'react-native';
import Advertisement from '../components/Advertisement';

const HomeScreen = ({navigation}) => {
return (
    <View style={styles.mainContainer}>
      <View style={styles.logoContainer}>
        <Image style={styles.logo}
        source={require('../assets/TPLookupLogo.png')} 
        style={{height: 200, width: 350, marginBottom: 40}} 
        resizeMode="contain">
        </Image>
      </View>
      <View style={styles.btnsContainer}>
        <Button 
        style={styles.button}
        appearance="outline"
        onPress={()=>{console.log('To New User')}}
        title='New User'
        />
        <Button 
        style={styles.button} 
        appearance="outline"
        onPress={()=>{console.log('To Login')}}
        title='Login'
        />
      </View>
      <View style={styles.adContainer}>
        <Advertisement/>
      </View>
    </View>
    );
}

const styles = StyleSheet.create({
  mainContainer: {
    flex: 1,
    justifyContent: 'center', 
    alignItems: 'center',
  },
  logoContainer: {
    flex: 4,
    justifyContent: 'flex-end', 
    alignItems: 'center'
  },
  btnsContainer: {
    flex: 4,
    width: '40%',
    justifyContent: 'flex-start', 
  },
  button: {
    marginVertical: 4,
    },
  adContainer: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'black'
  }
})

export default HomeScreen; 



AppNavigator:

import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from '../screens/HomeScreen';
import CreateNewAccountScreen from '../screens/CreateNewAccountScreen';

const AppNavigator = createStackNavigator(
    {
    Home: HomeScreen,
    CreateNewAccount: CreateNewAccountScreen

    },
    {
      initialRouteName: 'CreateNewAccount'
    }
  )

  export default AppNavigator;



CreateNewAccountScreen:

import React from 'react';
import { StyleSheet, View } from 'react-native'
import CreateAccountForm from '../components/CreateAccountForm';
import Advertisement from '../components/Advertisement';

const CreateNewAccountScreen = () => {
    return (
        <View style={styles.mainContainer}>
         <View style={styles.formContainer}>
           <CreateAccountForm/>
         </View>
         <View style={styles.adContainer}>
           <Advertisement/>
         </View> 
       </View>     
     );
}



const styles = StyleSheet.create({
    mainContainer:{
      flex: 1,
    },
    formContainer: {
      flex: 8,
    },
    adContainer: {
      flex: 1,
      justifyContent: 'center',
      backgroundColor: 'black'
    }
  })

CreateNewAccountScreen.navigationOptions = {
    headerTitle: 'Create Account'
}

export default CreateNewAccountScreen;



CreateAccountForm:

import React, { useState } from 'react';
import { StyleSheet, View, Input, Button } from 'react-native';

const CreateAccountForm = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [company, setCompany] = useState('');
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [address, setAddress] = useState('');
    const [city, setCity] = useState('');
    const [stateName, setStateName] = useState('');
    const [zip, setZip] = useState('');

    const onChangeEmailHandler = value => {
        setEmail(value);
    }

    const onChangePasswordHandler = value => {
        setPassword(value);
    }

    const onChangeCompanyHandler = value => {
        setCompany(value);
    }

    const onChangeFirstNameHandler = value => {
        setFirstName(value);
    }

    const onChangeLastNameHandler = value => {
        setLastName(value);
    }

    const onChangeAddressHandler = value => {
       setAddress(value);
    }

    const onChangeCityHandler = value => {
        setCity(value);
    }

    const onChangeStateNameHandler = value => {
        setStateName(value)
    }

    const onChangeZipHandler = value => {
        setZip(value);
    }

    const RegisterUserHandler = props => {
        let emailLength = email.length;
        let passwordLength = password.length;
        if (emailLength === 0 || passwordLength === 0)
        {
            console.log('Email & Password cannot be blank.');
        }
        else
        {
            registerUser()
        }
    }

    async function registerUser () {
        let headers = {
            'X-Authorization': "",
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            };
        let body = JSON.stringify({
            Email: email,
            Password: password,
            Company: company,
            FirstName: firstName,
            LastName: lastName,
            Address: address,
            City: city,
            State: stateName,
            Zipcode: zip
        })
        let response = await fetch('', 
        {
            method: 'POST',
            headers: headers,
            body: body
        });
        let responseJson = await response.json()
    }

    return (
        <View style={styles.mainContainer}>
                <Input
                style={styles.input}
                type="text"
                value={email}
                placeholder="Email"
                onChangeText={onChangeEmailHandler}
                />
                <Input
                style={styles.input}
                type="text"
                value={password}
                placeholder="Password"
                onChangeText={onChangePasswordHandler}
                />
                <Input
                style={styles.input}
                type="text"
                value={company}
                placeholder="Company"
                onChangeText={onChangeCompanyHandler}
                />
                <Input
                style={styles.input}
                value={firstName}
                placeholder="First Name"
                onChangeText={onChangeFirstNameHandler}
                />
                <Input
                style={styles.input}
                value={lastName}
                placeholder="Last Name"
                onChangeText={onChangeLastNameHandler}
                />
                <Input
                style={styles.input}
                value={address}
                placeholder="Address"
                onChangeText={onChangeAddressHandler}
                />
                <View style={styles.rowInputsContainer}>
                    <Input 
                    style={styles.input}
                    value={city}
                    style={styles.rowInput}
                    placeholder="City"
                    onChangeText={onChangeCityHandler}
                    />
                    <Input
                    style={styles.input}
                    value={stateName}
                    style={{...styles.rowInput, ...styles.centerRowInput}}
                    placeholder="State"
                    onChangeText={onChangeStateNameHandler}
                    />
                    <Input
                    style={styles.input}
                    value={zip}
                    style={styles.rowInput}
                    placeholder="Zip"
                    onChangeText={onChangeZipHandler}
                    />
                </View>
                <Button 
                style={styles.btn}
                onPress={RegisterUserHandler}
                title='Register'
                />
        </View>
    )   
}

const styles = StyleSheet.create({
    mainContainer: {
      flex: 1,
      width: '75%',
      alignSelf: 'center',
      justifyContent: 'center',
    },
    rowInputsContainer: {
        display: 'flex',
        flexDirection: 'row',
        marginBottom: 16
    },
    rowInput: {
        flexGrow: 1,
    },
    centerRowInput: {
        marginHorizontal: 4
    },
    input: {
        marginVertical: 8
    }
})

export default CreateAccountForm;

在我的第一个应用程序中,这种完全相同的设置使一切正常,没有任何问题。所以我不明白我哪里出错了。任何帮助,非常感谢,谢谢,和平!

【问题讨论】:

  • 请将代码 sn-p 缩减为仅用于说明问题所需的代码。
  • 另外,如何导入CreateAccountForm
  • @devserkan 在 CreateNewAccountScreen 的顶部我有: import CreateAccountForm from '../components/CreateAccountForm';
  • 如果CreateAccountForm 呈现(返回)只是一段文字,它是否有效?
  • @devserkan 是的!如果我只是放一个&lt;Text&gt;Hello from CreateAccountForm&lt;/Text&gt; 它就可以了!当我在&lt;View style={styles.mainContainer}&gt; 中添加所有其他内容时...在我的第一个项目中效果很好?。

标签: javascript reactjs react-native expo react-native-navigation


【解决方案1】:

React Native 有 TextInput 组件而不是 Input 组件。请在 CreateAccountForm 中导入时检查一下。

【讨论】:

    猜你喜欢
    • 2012-09-27
    • 2021-11-28
    • 2011-07-04
    • 2014-03-23
    • 2016-12-30
    • 2019-07-21
    • 2012-10-22
    • 2022-01-15
    • 2011-04-30
    相关资源
    最近更新 更多