为啥我不能让我的 RN 应用程序在本地运行以与本地 api 服务器通信?
Posted
技术标签:
【中文标题】为啥我不能让我的 RN 应用程序在本地运行以与本地 api 服务器通信?【英文标题】:Why can't I get my RN app running locally to talk to a local api server?为什么我不能让我的 RN 应用程序在本地运行以与本地 api 服务器通信? 【发布时间】:2019-06-25 06:08:05 【问题描述】:我有一个 React Native 前端和一个 Rails API 后端,但我似乎无法成功登录。
当我重新加载 RN 模拟器时,我确实收到以下消息:
RCTBridge 需要 dispatch_sync 来加载 RCTDevLoadingView。这可能 导致死锁
老实说,我不知道这是否相关。
我确实知道相关的错误是当我得到:
服务器:TypeError:网络请求失败
我可以采取哪些步骤来解决此问题?
我确实可以访问前端和后端代码库。
我想知道问题是否出在这个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
,但它什么也没做。
【问题讨论】:
你最好分享一些代码行 xD 【参考方案1】:对于 android 模拟器,您必须使用您的 IP 地址而不是 localhost。例如,使用:
fetch('http://000.000.000:3000/login',
method: 'POST',
headers:
Accept: 'application/json',
'Content-Type': 'application/json',
,
body: params,
)
您还必须允许 http:// 请求。打开 info.plist (ProjectFolder->ios->ProjectFolder->info.plist) 并在前面添加以下内容:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
见:https://***.com/a/48946478/10987825
【讨论】:
Noah,Mac 模拟器呢? 您还必须对所有常规的 http 请求。查看更新的答案以上是关于为啥我不能让我的 RN 应用程序在本地运行以与本地 api 服务器通信?的主要内容,如果未能解决你的问题,请参考以下文章
为啥这个 scrollLeft JS 函数不能在我的本地 wordpress 网站上运行?
为啥我的 ReactJS 应用程序在本地运行但不在 Azure 中运行?