代码之家  ›  专栏  ›  技术社区  ›  Daniel

为什么我不能让我的RN应用程序在本地运行以与本地api服务器对话?

  •  0
  • Daniel  · 技术社区  · 6 年前

    我有一个React本地前端和一个Rails API后端,我似乎无法成功登录。

    当我重新加载RN模拟器时,会收到以下消息:

    RCTBridge需要调度同步以加载RCTDevLoadingView。今年五月 导致死锁

    我真的不知道这是否相关。

    服务器:类型错误:网络请求失败

    我可以采取什么步骤来解决这个问题?

    我可以访问前端和后端代码库。

    app/containers/LoginScreen/index.js :

    import React from 'react';
    import { ActivityIndicator, StatusBar, Text, View, Linking, Image, TouchableWithoutFeedback, TouchableOpacity, Platform, Keyboard } from 'react-native';
    import Analytics from 'react-native-analytics-segment-io';
    import KeyboardSpacer from 'react-native-keyboard-spacer';
    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import _ from 'lodash';
    import { Images, Colors } from '../../themes';
    import { loginUser, getMeQuestions, getMeAnswers, pullOnLoadData, setLoggingIn } from '../../reducers/userReducer';
    import { getModuleInfo, getLessonInfo } from '../../reducers/lessonModuleReducer';
    import { FrigateButton, FrigateTextInput, HeaderBackButton, NavRightIcon } from '../../components';
    import styles from './styles';
    
    class LoginScreen extends React.Component {
      static getDerivedStateFromProps(nextProps, prevState) {
        if (!nextProps.id) {
          return {};
        }
        if (nextProps.id && nextProps.lessons.length > 0 && nextProps.modules.length > 0) {
          if (!prevState.loadedData) {
            nextProps.pullOnLoadData(nextProps.id);
            if (!nextProps.signedCurrentTerms) {
              Analytics.identify('user_id', { id: nextProps.id, email: nextProps.email });
              nextProps.navigation.navigate('TOSPP');
            } else {
              Analytics.identify('user_id', { id: nextProps.id, email: nextProps.email });
              nextProps.navigation.navigate('TabNavigator');
            }
            return { ...prevState, loadedData: true };
          }
        }
        return {};
      }
    
      constructor(props) {
        super(props);
        this.state = {
          username: '',
          password: '',
          loadedData: false,
        };
        this.loginPressed = this.loginPressed.bind(this);
      }
    
      loginPressed() {
        Analytics.track('Login Pressed', { email: this.state.username });
        this.props.setLoggingIn(true);
        Keyboard.dismiss();
        this.props.login(
          this.state.username,
          this.state.password,
        );
      }
    
      render() {
        return (
          <View
            testID="signupScreen"
            style={styles.mainContainer}
          >
            <StatusBar barStyle="light-content" />
            <Image source={Images.background} style={styles.backgroundImage} />
            <View style={styles.brand}>
              <Image source={Images.logo} style={styles.logoImage} />
            </View>
            {!this.props.token &&
              <View style={styles.textInputs}>
                <FrigateTextInput
                  onChangeText={text => this.setState({ username: text })}
                  label="EMAIL"
                  placeholder="EMAIL"
                  value={this.state.username}
                  keyboardType="email-address"
                />
                <FrigateTextInput
                  onChangeText={text => this.setState({ password: text })}
                  label="PASSWORD"
                  placeholder="PASSWORD"
                  secureTextEntry
                  value={this.state.password}
                />
                <TouchableOpacity
                  onPress={() => {
                    // Analytics.track('Forgot Password Pressed', { email: this.state.username });
                    this.props.navigation.navigate('ForgotPassword');
                    // Linking.openURL('http://thirdelement.herokuapp.com/users/password/new')
                  }}
                >
                  <View style={{ alignItems: 'flex-end', paddingRight: 20, paddingTop: 5 }}>
                    <Text style={{ color: 'white' }}>Forgot Password?</Text>
                  </View>
                </TouchableOpacity>
              </View>
            }
            {this.props.token &&
              <View style={styles.activityIndicator}>
                <ActivityIndicator size="large" />
              </View>
            }
            {!this.props.token &&
              <View style={styles.actionButtons}>
                <FrigateButton
                  title="Log In"
                  disabled={!_.every([
                    this.state.username,
                    this.state.password,
                  ], Boolean)}
                  onPress={this.loginPressed}
                />
              </View>
            }
            {Platform.OS === 'ios' &&
              <KeyboardSpacer />
            }
          </View>
        );
      }
    }
    
    LoginScreen.propTypes = {
      login: PropTypes.func.isRequired,
      navigation: PropTypes.shape({
        goBack: PropTypes.func,
      }).isRequired,
      token: PropTypes.string,
    };
    
    LoginScreen.defaultProps = {
      token: null,
    };
    
    LoginScreen.navigationOptions = props => ({
      title: 'Welcome Back',
      headerLeft: <HeaderBackButton onPress={() => props.navigation.goBack()} />,
      headerRight: <NavRightIcon />,
      headerStyle: {
        backgroundColor: 'black',
        shadowColor: 'transparent',
        borderBottomWidth: 0,
      },
      headerTintColor: Colors.thirdElementOrange,
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    });
    
    
    const mapStateToProps = state => ({
      email: state.user.email,
      id: state.user.id,
      token: state.user.token,
      lessons: state.lessonModules.lessons,
      modules: state.lessonModules.modules,
      signedCurrentTerms: state.user.signedCurrentTerms,
    });
    
    const mapDispatchToProps = dispatch => ({
      login: (u, p) => dispatch(loginUser(u, p)),
      getModules: () => dispatch(getModuleInfo()),
      getLessons: () => dispatch(getLessonInfo()),
      getMeQuestions: () => dispatch(getMeQuestions()),
      getMeAnswers: () => dispatch(getMeAnswers()),
      pullOnLoadData: id => dispatch(pullOnLoadData(id)),
      setLoggingIn: value => dispatch(setLoggingIn(value)),
    });
    
    export default connect(
      mapStateToProps,
      mapDispatchToProps,
    )(LoginScreen);
    

    我进入了 Info.plist 并配置为:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    

    这又给了我一个类似于这篇文章的错误:

    What is the meaning of 'No bundle URL present' in react-native?

    我跑了 rm -rf ios/build/; kill $(lsof -t -i:8081); react-native run-ios ,但什么也没做。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Noah    6 年前

    对于Android模拟器,必须使用IP地址而不是本地主机。例如,使用:

    fetch('http://000.000.000:3000/login', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: params,
    })
    

    您还必须允许http://requests。打开info.plist(ProjectFolder->ios->ProjectFolder->info.plist),并在前面添加以下内容:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    

    https://stackoverflow.com/a/48946478/10987825