不变违规:元素类型无效:应为字符串或类/函数,但未定义

时间:2019-03-03 03:04:27

标签: react-native error-handling undefined

我已经搜寻并实施了整整12个小时可以发现的所有错误信息。我被困住了,我试图重建我的本机应用程序。我真的是在这最后一根稻草。我知道其他人已经回答了这个问题,但是我尝试过这个问题的最流行答案,但绝对没有运气。我使用EXPO INIT构建了我的应用程序。这是我的代码package.json文件,以及出现的错误。 I have multiple common files that are functional components. If I comment out the TextFieldGroup on my SignUp page, it just errors to the next functional component CalendarFieldGroup当我单击主页上的“注册”按钮时,它将返回错误屏幕。我也将发布App.js文件。

// Not all of the code, just what is needed to help diagnose the problem hopefully
import { Provider } from 'react-redux';
import store from './store';

import LoginOrSignUp from './src/components/auth/LoginOrSignUp';
import Register from './src/components/auth/SignUp';
import Login from './src/components/auth/Login';

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <NativeRouter>
          <View style={styles.container}>
            <Switch>
              {/*Public Routes*/}
              <Route exact path="/login-or-sign-up" component={LoginOrSignUp} />
              <Route exact path="/sign-up" component={Register} />
              <Route exact path="/login" component={Login} />
              <Route

import React, { Component } from 'react';
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';

import { withRouter, Link } from 'react-router-native';
import { connect } from 'react-redux';
import moment from 'moment';

import { registerUser } from '../../actions/authActions';
import { clearErrors } from '../../actions/errorActions';

import BackButton from '../common/BackButton';
import Spinner from '../common/Spinner';
import TextFieldGroup from '../common/TextFieldGroup';
import CalendarFieldGroup from '../common/CalendarFieldGroup';
import SelectButtonGroup from '../common/SelectButtonGroup';

class SignUp extends Component {
  state = {
    firstName: '',
    lastName: '',
    email: '',
    password: '',
    password2: '',
    location: '',
    dateOfBirth: '',
    sex: '',
    selectedIndex: -1,
    errors: {}
  };

  componentDidMount() {
    if (this.props.auth.isAuthenticated) {
      this.props.history.push('/');
    }
    if (this.props.errors) {
      this.props.clearErrors();
    }
  }

  static getDerivedStateFromProps(nextProps) {
    if (nextProps.errors) {
      return { errors: nextProps.errors };
    }
    return null;
  }

  componentDidUpdate(prevProps) {
    if (prevProps.errors !== this.props.errors) {
      this.setState({ errors: this.props.errors });
    }
  }

  onChangeText = (text, field) => {
    this.setState({
      [field]: text
    });
  };

  onDateChange = (newDate, field) => {
    this.setState({
      [field]: newDate
    });
  };

  updateIndex = selectedIndex => {
    const sex = selectedIndex === 0 ? 'male' : 'female';
    this.setState({
      sex,
      selectedIndex
    });
  };

  onSubmit = e => {
    e.preventDefault();
    const newUser = {
      firstName: this.state.firstName,
      lastName: this.state.lastName,
      email: this.state.email.toLowerCase(),
      password: this.state.password,
      password2: this.state.password2,
      dateOfBirth: this.state.dateOfBirth,
      location: this.state.location,
      sex: this.state.sex
    };

    this.props.registerUser(newUser, this.props.history);
  };

  render() {
    const { errors } = this.state;
    const { loading } = this.props.auth;
    const dob = moment(
      new Date(this.state.dateOfBirth),
      'MMMM Do YYYY, h:mm:ss a'
    ).format('MMMM Do YYYY');

    let signUpContent;

    if (loading) {
      signUpContent = <Spinner />;
    } else {
      signUpContent = (
        <View style={styles.container}>
          <BackButton to="/login-or-sign-up" />
          <Text style={styles.signup}>Create an Account</Text>
          <Text style={styles.time}>Find Time To Live Life</Text>
          <View>
            <TextFieldGroup
              label="First Name"
              placeholder="Please enter your first name..."
              name="firstName"
              type="text"
              value={this.state.firstName}
              onChangeText={text => this.onChangeText(text, 'firstName')}
              error={errors.firstName}
            />

            <TextFieldGroup
              label="Last Name"
              placeholder="Please enter your last name..."
              name="lastName"
              type="text"
              value={this.state.lastName}
              onChangeText={text => this.onChangeText(text, 'lastName')}
              error={errors.lastName}
            />

            <TextFieldGroup
              label="Email Address"
              placeholder="Please enter your email address..."
              name="email"
              type="email"
              value={this.state.email}
              onChangeText={text => this.onChangeText(text, 'email')}
              error={errors.email}
            />

            <TextFieldGroup
              label="Location"
              placeholder="Please enter your current location..."
              name="location"
              type="text"
              value={this.state.location}
              onChangeText={text => this.onChangeText(text, 'location')}
              error={errors.location}
            />

            <TextFieldGroup
              label="Password"
              placeholder="Please enter a password..."
              name="password"
              type="password"
              secureTextEntry={true}
              value={this.state.password}
              onChangeText={text => this.onChangeText(text, 'password')}
              error={errors.password}
            />

            <TextFieldGroup
              label="Confirm Password"
              placeholder="Please re-enter your password..."
              name="password2"
              type="password"
              secureTextEntry={true}
              value={this.state.password2}
              onChangeText={text => this.onChangeText(text, 'password2')}
              error={errors.password2}
            />

            <View style={styles.calendar}>
              <CalendarFieldGroup
                label="Date of Birth"
                date={this.state.dateOfBirth}
                placeholder="Please enter your birthdate..."
                onDateChange={date => this.onDateChange(date, 'dateOfBirth')}
                error={errors.dateOfBirth}
              />
              <Text>
                {dob !== 'Invalid date'
                  ? dob
                  : 'Please enter your birth date...'}
              </Text>
            </View>

            <SelectButtonGroup
              label="Please select your gender..."
              onPress={this.updateIndex}
              selectedIndex={this.state.selectedIndex}
              buttons={['Male', 'Female']}
              error={errors.sex}
            />

            <TouchableOpacity onPress={this.onSubmit} style={styles.btn}>
              <Text>Sign Up</Text>
            </TouchableOpacity>

            <Link to="/terms-of-service">
              <Text style={styles.terms}>
                Terms of Service &amp; Privacy Policy
              </Text>
            </Link>
          </View>
        </View>
      );
    }
    return <View>{signUpContent}</View>;
  }
}

const styles = StyleSheet.create({
  container: {},
  signup: {
    fontSize: 20,
    color: 'blue',
    margin: 5,
    marginLeft: 'auto',
    marginRight: 'auto'
  },
  time: {
    fontSize: 12,
    color: 'grey',
    margin: 5,
    marginLeft: 'auto',
    marginRight: 'auto'
  },
  calendar: {
    marginLeft: 'auto',
    marginRight: 'auto'
  },
  btn: {
    alignItems: 'center',
    backgroundColor: '#DDDDDD',
    padding: 10,
    marginTop: 10
  },
  terms: {
    color: 'grey',
    fontSize: 10,
    marginTop: 5,
    marginLeft: 'auto',
    marginRight: 'auto'
  }
});

SignUp.propTypes = {
  registerUser: PropTypes.func.isRequired,
  clearErrors: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { registerUser, clearErrors }
)(withRouter(SignUp));

import React, { Component } from 'react';
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';

import { Link } from 'react-router-native';
import { connect } from 'react-redux';

import { loginUser, clearUserEmail } from '../../actions/authActions';
import { clearErrors } from '../../actions/errorActions';

import BackButton from '../common/BackButton';
import Spinner from '../common/Spinner';
import TextFieldGroup from '../common/TextFieldGroup';

class Login extends Component {
  state = {
    email: '',
    password: '',
    errors: {}
  };

  componentDidMount() {
    if (this.props.auth.isAuthenticated) {
      this.props.history.push('/');
    }
    if (this.props.errors) {
      this.props.clearErrors();
    }
    if (this.props.auth.email) {
      this.props.clearUserEmail();
    }
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.errors) {
      return { errors: nextProps.errors };
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevProps.errors !== this.props.errors) {
      this.setState({
        errors: this.props.errors
      });
    }
    if (this.props.auth.isAuthenticated) {
      this.setState({ isAuthenticated: this.props.auth.isAuthenticated });
      this.props.history.push('/');
    }
    if (this.props.errors.email === 'You must confirm your email') {
      this.props.history.push('/email-confirmation-email');
    }
  }

  onChangeText = (text, field) => {
    this.setState({
      [field]: text
    });
  };

  onSubmit = e => {
    e.preventDefault();

    const userData = {
      email: this.state.email.toLowerCase(),
      password: this.state.password
    };

    this.props.loginUser(userData);
  };

  render() {
    const { errors } = this.state;
    const { loading } = this.props.auth;

    let loginContent;

    if (loading) {
      loginContent = <Spinner />;
    } else {
      loginContent = (
        <View style={styles.container}>
          <BackButton to="/login-or-sign-up" />
          <Text style={styles.login}>Login</Text>
          <Text style={styles.time}>Find time to Hang Out</Text>

          <TextFieldGroup
            label="Email Address"
            placeholder="Please enter your email address..."
            name="email"
            type="email"
            value={this.state.email}
            onChangeText={text => this.onChangeText(text, 'email')}
            error={errors.email}
          />

          <TextFieldGroup
            label="Password"
            placeholder="Please enter a password..."
            name="password"
            type="password"
            secureTextEntry={true}
            value={this.state.password}
            onChangeText={text => this.onChangeText(text, 'password')}
            error={errors.password}
          />

          <TouchableOpacity onPress={this.onSubmit} style={styles.btn}>
            <Text style={styles.time}>Login</Text>
          </TouchableOpacity>

          <View style={styles.forgotPassword}>
            <Link to="/forgot-password-email">
              <Text style={styles.forgotPassowrdText}>forgot password?</Text>
            </Link>
          </View>
        </View>
      );
    }

    return <View>{loginContent}</View>;
  }
}

const styles = StyleSheet.create({
  container: {},
  login: {
    fontSize: 20,
    color: 'blue',
    marginLeft: 'auto',
    marginRight: 'auto'
  },
  time: {
    fontSize: 12,
    color: 'grey',
    margin: 5,
    marginLeft: 'auto',
    marginRight: 'auto'
  },
  btn: {
    alignItems: 'center',
    backgroundColor: '#DDDDDD',
    padding: 10,
    marginTop: 10
  },
  forgotPassword: {
    height: 16,
    marginTop: 100,
    marginLeft: 'auto',
    marginRight: 'auto'
  },
  forgotPassowrdText: {
    fontSize: 12,
    color: '#d15555'
  }
});

Login.propTypes = {
  loginUser: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { loginUser, clearErrors, clearUserEmail }
)(Login);

import React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';

import { FormLabel, FormInput } from 'react-native-elements';

const TextFieldGroup = ({
  label,
  type,
  secureTextEntry,
  placeholder,
  name,
  value,
  onChangeText,
  disabled,
  info,
  error
}) => {
  return (
    <View style={styles.formGroup}>
      {error ? (
        <View>
          <FormLabel>
            {label} <Text style={styles.error}>{error}</Text>
          </FormLabel>
        </View>
      ) : (
        <FormLabel>{label}</FormLabel>
      )}

      <FormInput
        type={type}
        secureTextEntry={secureTextEntry}
        placeholder={placeholder}
        name={name}
        value={value}
        onChangeText={onChangeText}
        disabled={disabled}
      />
      {info && <Text style={styles.info}>{info}</Text>}
    </View>
  );
};

const styles = StyleSheet.create({
  formGroup: {},
  info: {},
  error: {
    fontSize: 8,
    color: 'red'
  }
});

TextFieldGroup.propTypes = {
  label: PropTypes.string,
  type: PropTypes.string.isRequired,
  secureTextEntry: PropTypes.bool,
  placeholder: PropTypes.string,
  name: PropTypes.string.isRequired,
  value: PropTypes.string.isRequired,
  onChangeText: PropTypes.func.isRequired,
  disabled: PropTypes.string,
  info: PropTypes.string,
  error: PropTypes.string
};

TextFieldGroup.defaultProps = {
  type: 'text',
  value: '',
  secureTextEntry: false
};

export default TextFieldGroup;

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "eject": "expo eject"
  },
  "dependencies": {
    "axios": "^0.18.0",
    "expo": "^32.0.0",
    "jwt-decode": "^2.2.0",
    "moment": "^2.24.0",
    "react": "16.5.0",
    "react-moment": "^0.8.4",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "react-native-datepicker": "^1.7.2",
    "react-native-elements": "^1.1.0",
    "react-native-scripts": "^2.0.1",
    "react-native-vector-icons": "^6.3.0",
    "react-redux": "^6.0.1",
    "react-router-native": "^4.3.0",
    "redux": "^4.0.1",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "babel-preset-expo": "^5.0.0"
  },
  "private": true
}

2 个答案:

答案 0 :(得分:0)

要像现在一样使用<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.things.contrib.driver.adc"> <application> <uses-library android:required="false" android:name="com.google.android.things"/> </application> </manifest> ,请使其成为TextFieldGroup的{​​{1}}。 IMO,这将是理想的解决方案

class

如果您希望将其用作功能,则可以

React.Component

然后这样称呼它,

export default class TextFieldGroup extends React.Component {
  render() {
    ...
  }
}

答案 1 :(得分:0)

所以我只是想通了。 软件包react-native-elements@1.1.0给了我这个错误。我回滚到版本react-native-elements@0.19.1。他们在6天前更新了他们的软件包,而我已经有7天没有从事我的项目了。我想今天早上开始工作时将软件包更新为最新版本,混乱不堪!