我无法通过 Android 模拟器使用 React Native 将数据发布到 Express 后端。该应用程序的目标是允许客户发布微任务请求,例如家务和草坪护理,其中所有数据都将存储到 AWS RDS MySQL 服务器。另一方面,自由职业者可以通过提要查看客户帖子。 (有关更多背景信息,请访问:https://askfavr.com)现在您已经了解了该问题的背景。
import React, { Component } from 'react';
import {
StyleSheet, Text, View, Image,
TextInput, KeyboardAvoidingView,
TouchableOpacity, AsyncStorage, ScrollView
} from "react-native";
export default class App extends React.Component {
state = {
request: {
C_Name: '', //this is a placeholder for the addRequest() method
Email: '',
Phone: '',
Category: '',
Time_Length: '',
Street: '',
City: '',
C_State: '',
Zip: '',
Finish_Before: '',
Price: '',
Details: ''
}
}
/* Just like getRequests, addRequest does exactly what its named as well. It adds a request
to the MySQL database following the initialization of the request state. The addRequest()
uses the post method which then returns are query string containing the new data submitted */
addRequest = _ => {
const { request } = this.state;
//query string set to remote server
fetch(`http://192.168.56.1:4000/requests/add?C_Name=${request.C_Name}&Email=${request.Email}&Phone=${request.Phone}&Category=${request.Category}&Time_Length=${request.Time_Length}&Street=${request.Street}&City=${request.City}&C_State=${request.C_State}&Zip=${request.Zip}&Finish_Before=${request.Finish_Before}&Price=${request.Price}&Details=${request.Details}`)
.catch(err => console.error(err))
}
render() {
const { request } = this.state; //set state for addRequest()
return (
<KeyboardAvoidingView behavior='padding' style={styles.wrapper}>
<Text style={styles.header}> Yardwork Request </Text>
<ScrollView>
<TextInput
style={styles.TextInput} placeholder='Name:' value={request.C_Name}
onChangeText={Name => this.setState(request.C_Name)}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Email:' value={request.Email}
onChangeText={e => this.setState({ request: { ...request, Email: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Phone:' value={request.Phone}
onChangeText={e => this.setState({ request: { ...request, Phone: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Category:' value={request.Category}
onChangeText={e => this.setState({ request: { ...request, Category: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Time of Job:' value={request.Time_Length}
onChangeText={e => this.setState({ request: { ...request, Time_Length: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Street:' value={request.Street}
onChangeText={e => this.setState({ request: { ...request, Street: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='City:' value={request.City}
onChangeText={e => this.setState({ request: { ...request, City: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='State:' value={request.C_State}
onChangeText={e => this.setState({ request: { ...request, C_State: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Zip:' value={request.Zip}
onChangeText={e => this.setState({ request: { ...request, Zip: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Complete By:' value={request.Finish_Before}
onChangeText={e => this.setState({ request: { ...request, Finish_Before: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Price:' value={request.Price}
onChangeText={e => this.setState({ request: { ...request, Price: e.target.value } })}
underlineColorAndroid='black'
/>
<TextInput
style={styles.TextInput} placeholder='Details:' value={request.Details}
onChangeText={e => this.setState({ request: { ...request, Details: e.target.value } })}
underlineColorAndroid='black'
/>
<TouchableOpacity
style={styles.btn}
onPress={this.addRequest}>
<Text> Request </Text>
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
wrapper: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#FFF',
paddingLeft: 40,
paddingRight: 40,
},
header: {
fontSize: 24,
marginTop: 25,
color: '#000000',
fontWeight: 'bold',
},
TextInput: {
alignSelf: 'stretch',
padding: 16,
marginBottom: 20,
borderRadius: 12,
color: '#000000',
fontSize: 16,
//backgroundColor: '#fff',
},
btn: {
alignSelf: 'stretch',
backgroundColor: 'green',
padding: 20,
borderRadius: 12,
alignItems: 'center',
},
small: {
fontSize: 15,
color: '#000000',
paddingTop: 10,
},
});
当我尝试在 React Native 中运行本质上相同的东西时,我收到此错误
setState(...) 接受要更新的状态变量对象或返回状态变量对象的函数
但是在 Plain React 中我可以毫无问题地使用几乎完全相同的代码并轻松发布数据
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
requests: [], //null state for the getRequests() method
request: {
C_Name: '', //this is a placeholder for the addRequest() method
Email: '',
Phone: '' ,
Category: '',
Time_Length:'' ,
Street:'' ,
City:'' ,
C_State:'' ,
Zip:'' ,
Finish_Before:'' ,
Price: '',
Details: ''
}
}
/* Mounts the "getRequests" to display on the screen, instead of writing the
full method within the componentDidMount()
componentDidMount() Purpose: this method takes place before rendering to
essentially change the state of the arrays and variables if they are no
longer null. */
componentDidMount() {
this.getRequests();
}
getRequests = _ => {
fetch('http://192.168.56.1:4000/requests')
.then( response => response.json())
.then(response => this.setState({ requests: response.data}))
.catch( err => console.error(err))
}
/* Just like getRequests, addRequest does exactly what its named as well. It adds a request
to the MySQL database following the initialization of the request state. The addRequest()
uses the post method which then returns are query string containing the new data submitted */
addRequest =_ => {
const { request } = this.state;
//query string set to remote server
fetch(`http://localhost:4000/requests/add?C_Name=${request.C_Name}&Email=${request.Email}&Phone=${request.Phone}&Category=${request.Category}&Time_Length=${request.Time_Length}&Street=${request.Street}&City=${request.City}&C_State=${request.C_State}&Zip=${request.Zip}&Finish_Before=${request.Finish_Before}&Price=${request.Price}&Details=${request.Details}`)
.then(this.getRequests)
.catch(err => console.error(err))
}
//Fields of Data for a FAVR Request:
//idyard_record, time_posted, C_Name, Email, Phone, Category, Time_Length, Street, City, C_State, Zip, Finish_Before, Price
//Details, RequestID, Proposals
renderRequest = ({ idyard_record, C_Name, Category }) =>
<div key={idyard_record}>{C_Name}: <b>{Category} </b><br/><br/> </div> //displays all requests from the MySQL data similar to a flatlist
render() {
const { requests, request} = this.state; //set state for getRequests() && getRequest()
const mainDiv = {
align: 'center',
justifyContent: 'center',
flex: '1',
margin: '2%'
}
const divStyle = {
margin: '2%',
};
const inputBorder = {
borderColor: 'lightgrey',
padding: '5px',
marginTop: '1%',
marginLeft: '1%'
}
return (
<div className="App" style={mainDiv} >
{requests.map(this.renderRequest)}
<div>
<div style={divStyle} >
<label style={{align: 'left'}} > Name: </label>
<input style={inputBorder} value={request.C_Name}
onChange={e => this.setState({ request: {...request, C_Name: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Email: </label>
<input style={inputBorder} value={request.Email}
onChange={e => this.setState({ request: {...request, Email: e.target.value}})} />
</div>
<div style={divStyle} >
<label style={{textAlign: 'left'}} > Phone: </label>
<input style={inputBorder} value={request.Phone}
onChange={e => this.setState({ request: {...request, Phone: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Category: </label>
<input style={inputBorder} value={request.Category}
onChange={e => this.setState({ request: {...request, Category: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Time of Job: </label>
<input style={inputBorder} value={request.Time_Length}
onChange={e => this.setState({ request: {...request, Time_Length: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Street: </label>
<input style={inputBorder} value={request.Street}
onChange={e => this.setState({ request: {...request, Street: e.target.value}})} />
</div>
<div style={divStyle} >
<label> City: </label>
<input style={inputBorder} value={request.City}
onChange={e => this.setState({ request: {...request, City: e.target.value}})} />
</div>
<div style={divStyle} >
<label> State: </label>
<input style={inputBorder} value={request.C_State}
onChange={e => this.setState({ request: {...request, C_State: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Zip: </label>
<input style={inputBorder} value={request.Zip} placeholder='55901'
onChange={e => this.setState({ request: {...request, Zip: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Complete By: </label>
<input type="datetime-local" style={inputBorder} value={request.Finish_Before} placeholder='55901'
onChange={e => this.setState({ request: {...request, Finish_Before: e.target.value}})} />
</div>
<div style={divStyle} >
<label> Price: </label>
$<input type="number" style={inputBorder} value={request.Price} placeholder='$20'
onChange={e => this.setState({ request: { ...request, Price: e.target.value }})} />
</div>
<div style={divStyle} >
<label> Details: </label>
<textarea rows={3} style={inputBorder} value={request.Details}
onChange={e => this.setState({ request: { ...request, Details: e.target.value }})} />
</div>
<button onClick={this.addRequest}> Request FAVR </button>
</div>
</div>
);
}
}
export default App;
有人有解决这个问题的建议吗?我知道后端不是问题,因为普通的反应应用程序可以发布到它,并且模拟器/普通的反应应用程序可以毫无问题地显示来自 MySQL 数据库的数据。
有问题的似乎是这个:
onChangeText={Name => this.setState(request.C_Name)}
这一行位于 React Native 代码中,而不是普通的 React 代码中,所以这就是两者之间的区别。您应该传递
setState()
一个对象,例如:
this.setState({ request: {...request, C_Name: e.target.value}})
与您为其他人所做的类似。
我能够通过改变三件事来解决这个问题:
*所以代替这个:*
state = {
request: {
C_Name: '', //this is a placeholder for the addRequest() method
Email: '',
Phone: '',
Category: '',
Time_Length: '',
Street: '',
City: '',
C_State: '',
Zip: '',
Finish_Before: '',
Price: '',
Details: ''
}
}
你必须将状态变量更改为此
constructor(props) {
super(props)
this.state = {
request: {
C_Name: '', //this is a placeholder for the addRequest() method
Email: '',
Phone: '',
Category: '',
Time_Length: '',
Street: '',
City: '',
C_State: '',
Zip: '',
Finish_Before: '',
Price: '',
Details: ''
}
}
2. 其次,当您使用提交按钮时,我建议在提交功能中使用括号
而不是这个
addRequest = _ => {
const { request } = this.state;
//query string set to remote server
fetch(`http://192.168.56.1:4000/requests/add?C_Name=${request.C_Name}&Email=${request.Email}&Phone=${request.Phone}&Category=${request.Category}&Time_Length=${request.Time_Length}&Street=${request.Street}&City=${request.City}&C_State=${request.C_State}&Zip=${request.Zip}&Finish_Before=${request.Finish_Before}&Price=${request.Price}&Details=${request.Details}`)
.catch(err => console.error(err))
}
你必须将功能更改为:
addRequest = () => {
const { request } = this.state;
//query string set to remote server
fetch(`http://192.168.56.1:4000/requests/add?C_Name=${request.C_Name}&Email=${request.Email}&Phone=${request.Phone}&Category=${request.Category}&Time_Length=${request.Time_Length}&Street=${request.Street}&City=${request.City}&C_State=${request.C_State}&Zip=${request.Zip}&Finish_Before=${request.Finish_Before}&Price=${request.Price}&Details=${request.Details}`)
.catch(err => console.error(err))
}
所以不要使用这个
onChangeText={e => this.setState({ request: { ...request, Email: e.target.value } })}
忽略
e.target.value
并将其更改为类似的内容(当然为每个输入使用不同的变量)
onChangeText={(Email) => this.setState({ request: { ...request, Email: Email } })}
总而言之,确保状态在构造函数下传递,其次使用
() =>
作为提交函数而不是 _ =>
,最后确保正确传递输入对象。 记住,.target.value
不能像普通 React 那样与 React Native 一起使用。