React Native 发布/获取到后端

问题描述 投票:0回答:2

我无法通过 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 数据库的数据。

image of react native error

reactjs react-native android-emulator fetch-api
2个回答
0
投票

有问题的似乎是这个:

    onChangeText={Name => this.setState(request.C_Name)}

这一行位于 React Native 代码中,而不是普通的 React 代码中,所以这就是两者之间的区别。您应该传递

setState()
一个对象,例如:

    this.setState({ request: {...request, C_Name: e.target.value}})

与您为其他人所做的类似。


0
投票

我能够通过改变三件事来解决这个问题:

  1. 在 React Native 中,你不能单独拥有状态,你必须配置更改状态项以通过构造函数传递

*所以代替这个:*

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))
}
  1. 最后,您必须正确传递 onchange 文本。您不能像普通反应那样使用目标值。

所以不要使用这个

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 一起使用。

© www.soinside.com 2019 - 2024. All rights reserved.