反应中的axios put请求返回空

时间:2019-07-20 03:21:13

标签: reactjs axios

我对React和Call请求很陌生。我正在使用React,express,MySql和Sequelize构建一个全栈应用程序。 除了放置请求以编辑客户端信息外,其他所有操作都正常。我正在使用Axios进行这些调用,并且可以从应用程序中添加,查看和删除数据,但编辑部分无法正常工作。

当单击表单上的Submit按钮时,Put请求将返回一个空数组,而不是实际的修改数据。我的路线还可以(我相信),因为使用Postman进行测试就可以了。我几乎可以确定我的问题出在axios调用中使用的方法上,但是我不能仅仅找到使它工作的正确方法。任何帮助将不胜感激。

import React, { Component } from 'react';
import axios from 'axios';
import API from '../../utils/API';

class index extends Component {

constructor(props) {
    super(props);

    this.onChangeLastName = this.onChangeLastName.bind(this);
    this.onChangeFirstName = this.onChangeFirstName.bind(this);
    this.onChangePhone = this.onChangePhone.bind(this);
    this.onChangePetName = this.onChangePetName.bind(this);
    this.onChangeBreed = this.onChangeBreed.bind(this);
    this.onChangeNotes = this.onChangeNotes.bind(this);

    this.onSubmit = this.onSubmit.bind(this);
    this.state = {
        client: null
    }

}

componentDidMount() {

    let id = this.props.match.params.id
    API.getClient(id)
        .then(res => {
            this.setState({
                client: res.data
            })
            console.log(this.state.client.id)
        })
        .catch(error => console.log(error))
}


onChangeLastName(e) {
    this.setState({
        lastName: e.target.value
    });
}

onChangeFirstName(e) {
    this.setState({
        firstName: e.target.value
    });
}

onChangePhone(e) {
    this.setState({
        phone: e.target.value
    });
}

onChangePetName(e) {
    this.setState({
        petName: e.target.value
    });
}

onChangeBreed(e) {
    this.setState({
        breed: e.target.value
    });
}

onChangeNotes(e) {
    this.setState({
        notes: e.target.value
    });
}

onSubmit(e) {
    e.preventDefault();

    let obj = {
        lastName: this.state.client.lastName.value,
        firstName: this.state.client.firstName.value,
        phone: this.state.client.phone.value,
        petName: this.state.client.petName.value,
        breed: this.state.client.breed.value,
        notes: this.state.client.notes.value
    };

    let id = this.state.client.id

    axios.put("http://localhost:3000/api/clients/" + id, obj)

        // .then(alert("client Updated"))
        .then(res => console.log(res))
        .catch(error => console.log(error))

    this.props.history.push('/admin');
}

render() {

    const client = this.state.client ? (
        <div className="client">
            <h3 style={{ marginLeft: "60px" }}>Update Client</h3>

            <form onSubmit={this.onSubmit} style={{ padding: "60px" }}>
                <div className="form-group">
                    <label>Last Name: </label>
                    <input type="text"
                        className="form-control"
                        defaultValue={this.state.client.lastName}
                        onChange={this.onChangeLastName}
                    />
                </div>
                <div className="form-group">
                    <label>First Name: </label>
                    <input type="text"
                        className="form-control"
                        defaultValue={this.state.client.firstName}
                        onChange={this.onChangeFirstName}
                    />
                </div>
                <div className="form-group">
                    <label>Phone: </label>
                    <input type="text"
                        className="form-control"
                        defaultValue={this.state.client.phone}
                        onChange={this.onChangePhone}
                    />
                </div>
                <div className="form-group">
                    <label>Pet Name: </label>
                    <input type="text"
                        className="form-control"
                        defaultValue={this.state.client.petName}
                        onChange={this.onChangePetName}
                    />
                </div>
                <div className="form-group">
                    <label>Breed: </label>
                    <input type="text"
                        className="form-control"
                        defaultValue={this.state.client.breed}
                        onChange={this.onChangeBreed}
                    />
                </div>
                <div className="form-group">
                    <label>Notes: </label>
                    <input type="text"
                        className="form-control"
                        defaultValue={this.state.client.notes}
                        onChange={this.onChangeNotes}
                    />
                </div>

                <br />
                <div className="form-group">
                    <input type="submit" value="Update Client" 
                     className="btn btn-primary" />
                </div>
            </form>

        </div>
    ) : (
            <div className="center">Loading Client</div>
        )

    return (


            <div className="container">
                {client}
            </div>
        )
    }
}

export default index;

3 个答案:

答案 0 :(得分:1)

我认为这是因为您处理输入的onchange的方式。您想将onchange设置为您的状态下的客户端值。但是相反,您将其设置为状态本身。因此,当您构建要发送到后端的对象时,您将发送空数据,因为您尚未在状态中将任何数据设置为实际的客户端值,并且该值仍然为空。尝试使用控制台记录状态,您将了解我在说什么。同样,您要在每个要用来构建对象的状态值的末尾添加一个.value,这是不必要的。最后,您无需为每个输入指定一个onchange,只需为输入提供一个name属性,就可以像这样设置onchange处理程序:

onChange = e => {
  this.setState({
    [e.target.name]: e.target.value
  })
}

因此您的组件将类似于以下内容:

import React, { Component } from 'react';
import axios from 'axios';
import API from '../../utils/API';

class index extends Component {

constructor(props) {
    super(props);

    this.onChange = this.onChange.bind(this);

    this.onSubmit = this.onSubmit.bind(this);
    this.state = {
        client: null
    }

}

componentDidMount() {

    let id = this.props.match.params.id
    API.getClient(id)
        .then(res => {
            this.setState({
                client: res.data
            })
            console.log(this.state.client.id)
        })
        .catch(error => console.log(error))
}


onChange(e) {
    this.setState({
        client: {
             ...this.state.client,
             [e.target.name]: e.target.value
        }
    });
}


onSubmit(e) {
    e.preventDefault();

    let obj = {
        lastName: this.state.client.lastName,
        firstName: this.state.client.firstName,
        phone: this.state.client.phone,
        petName: this.state.client.petName,
        breed: this.state.client.breed,
        notes: this.state.client.notes
    };

    let id = this.state.client.id

    axios.put("http://localhost:3000/api/clients/" + id, obj)

        // .then(alert("client Updated"))
        .then(res => console.log(res))
        .catch(error => console.log(error))

    this.props.history.push('/admin');
}

render() {

    const client = this.state.client ? (
        <div className="client">
            <h3 style={{ marginLeft: "60px" }}>Update Client</h3>

            <form onSubmit={this.onSubmit} style={{ padding: "60px" }}>
                <div className="form-group">
                    <label>Last Name: </label>
                    <input type="text"
                        name="lastName"
                        className="form-control"
                        defaultValue={this.state.client.lastName}
                        onChange={this.onChange}
                    />
                </div>
                <div className="form-group">
                    <label>First Name: </label>
                    <input type="text"
                        name="firstName"
                        className="form-control"
                        defaultValue={this.state.client.firstName}
                        onChange={this.onChange}
                    />
                </div>
                <div className="form-group">
                    <label>Phone: </label>
                    <input type="text"
                        name="phone"
                        className="form-control"
                        defaultValue={this.state.client.phone}
                        onChange={this.onChange}
                    />
                </div>
                <div className="form-group">
                    <label>Pet Name: </label>
                    <input type="text"
                        name="petName"
                        className="form-control"
                        defaultValue={this.state.client.petName}
                        onChange={this.onChange}
                    />
                </div>
                <div className="form-group">
                    <label>Breed: </label>
                    <input type="text"
                        name="breed"
                        className="form-control"
                        defaultValue={this.state.client.breed}
                        onChange={this.onChange}
                    />
                </div>
                <div className="form-group">
                    <label>Notes: </label>
                    <input type="text"
                        name="notes"
                        className="form-control"
                        defaultValue={this.state.client.notes}
                        onChange={this.onChange}
                    />
                </div>

                <br />
                <div className="form-group">
                    <input type="submit" value="Update Client" 
                     className="btn btn-primary" />
                </div>
            </form>

        </div>
    ) : (
            <div className="center">Loading Client</div>
        )

    return (


            <div className="container">
                {client}
            </div>
        )
    }
}

export default index;

答案 1 :(得分:0)

这可能是因为您在调用this.props.history.push之后立即调用axios.post,实际上是在POST请求有机会返回响应之前进行重定向。

尝试将this.props.history.push('/admin')放在.then()内。

答案 2 :(得分:0)

您在这里做错了很多事情,

对于每个输入,您应该只具有1个onChange处理程序,每个输入都具有name属性才能与state一起使用。例如,

<input type="text"
    className="form-control"
    defaultValue={this.state.client.lastName}
    name="lastName" //Like this should add name for every input like below
    onChange={this.onChangeHandler} //This is a common onChangeHandler for every input should add in every input like below
/>


<input type="text"
    className="form-control"
    defaultValue={this.state.client.firstName}
    name="firstName"
    onChange={this.onChangeHandler}
/>

并且onChangeHandler函数应该是

onChangeHandler(e){
   this.setState({
      ...this.state.client,
      [e.target.name]:e.target.value
   })
}

最后您的onSubmit函数应该是

onSubmit(e) {
    e.preventDefault();

    let obj = {
        lastName: this.state.client.lastName, //Remove `.value` as we are getting values from state and not directly from input
        firstName: this.state.client.firstName,
        phone: this.state.client.phone,
        petName: this.state.client.petName,
        breed: this.state.client.breed,
        notes: this.state.client.notes
    };

    let id = this.state.client.id

    axios.put("http://localhost:3000/api/clients/" + id, obj)

        // .then(alert("client Updated"))
        .then(res => console.log(res))
        .catch(error => console.log(error))

    this.props.history.push('/admin');
}

注意:您不会在console.log中获得任何价值

 API.getClient(id)
   .then(res => {
       this.setState({
          client: res.data
       })
       console.log(this.state.client.id)
   })

由于seStateasync,因此您应在setState中使用callback来创建console.log,

 API.getClient(id)
    .then(res => {
       this.setState({
           client: res.data
       }, () => console.log(this.state.client.id)) //This is callback
    })