【问题标题】:axios put request in react is returning emptyaxios 将请求放入反应中返回空
【发布时间】:2019-07-20 03:21:13
【问题描述】:

我对 React 和 Call 请求很陌生。我正在使用 React、express、MySql 和 Sequelize 构建一个全栈应用程序。 除了编辑客户信息的 Put 请求外,一切正常。我正在使用 Axios 进行这些调用,我可以在应用程序中添加、查看和删除数据,但编辑部分不起作用。

点击表单上的提交按钮时,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;

【问题讨论】:

  • 我看不出上面的代码有什么问题。您可以使用 Chrome 开发工具中的网络选项卡来验证您的 api 请求和响应数据是否正确?

标签: reactjs axios


【解决方案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;

【讨论】:

  • 感谢您的回答。我按照您的建议修改了代码,但现在我在控制台上返回了一个状态为 200 的空对象,而不是一个空数组。仍然没有修改数据
  • 是的,Post、Get、Delete 和 Put 请求在使用 Postman 时工作得很好。我刚刚又试了一次,Put 请求让我返回一个编号为 1 的对象,并且在检查 mysql 工作台时它实际上更改了数据,所以我认为它可以工作
  • Ok console.log 在你的 axios 请求中发送 obj 和 id 以确保你发送正确的数据
  • 我在控制台记录了 id,它显示正常,但 obj 给我的信息与数据库中的信息相同
  • 您使用邮递员发布的数据与您发送的数据相同吗?在邮递员中,您将包含您的信息的普通对象发送到后端。您没有将数据包装在该对象内的键中。也许尝试发布您的服务器代码,以便我们也可以查看。
【解决方案2】:

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

尝试将this.props.history.push('/admin') 放入.then()

【讨论】:

    【解决方案3】:

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

    对于每个输入,您应该只有 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
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-03
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      • 2020-07-07
      相关资源
      最近更新 更多