如何使用axios从React表单发送POST请求?

时间:2019-07-15 13:54:54

标签: reactjs axios

这就像使用React和axios的CRUD。我有一些形式和输入的组件。该表单使用axios GET方法从express后端接收数据,并且显然没有问题。 但是第二项任务是更改输入中的数据,并使用axios POST将其发布到路由。由于某种原因,它无法从POST请求的所有输入中收集数据到json。 有人告诉我这是怎么了?

从后端请求的JSON看起来像这样:

{
    "data": [
        {
            "_id": "5d28a6fcec97b111c2f5867d",
            "phone": "+1 (111) 111 11 11",
            "email": "shutruk@gmail.com",
            "title": "khkjhkjhkj",
            "longTitle": "lkjlkjlkjlk",
            "introTitle": "Shutruk",
            "introLongTitle": "Shutruk-Nahhunte",
            "videoLink": "khkjhkjhkj",
            "introText": "lkjlkjlkjlk",
            "__v": 0
        }
    ]
}

以下是组件:

import React, { Component } from 'react';
import axios from 'axios';

class Misc extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      value: [],
      loading: true,
      error: false,
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }  
  onChange(e) {
    this.setState({ value: e.target.value });
  }
  componentDidMount() {
    axios.get('http://localhost:5555/data')
      .then(res => {
        const data = res.data.data; // get the data array instead of object
        this.setState({ data, loading: false });
      })
      .catch(err => { // log request error and prevent access to undefined state
        this.setState({ loading: false, error: true });
        console.error(err); 
      })
  }
  handleSubmit(e) {
    e.preventDefault();

    const data = {
      value: this.state.value
    };

    axios.post('http://localhost:5555/data', { data })
      .then(res => {
        console.log(data);
      })
  }
  render() {
    if (this.state.loading) {
      return(
        <div>
          <p> Loading... </p>
        </div>
      )
    }
    if (this.state.error || !this.state.data[0]) { // if request failed or data is empty don't try to access it either
      return(
        <div>
          <p> An error occured </p>
        </div>
      )
    }
    return (
      <form action="" onSubmit={this.handleSubmit}>
        <h2 className="center" >Change values</h2>
        <div className="center"><img src={require('../img/orn.png')} alt="" className="orn"/></div>
        <h5>Phone:</h5>
        <input type="text" name="phone" defaultValue={ this.state.data[0].phone } onChange={e => this.onChange(e)} />
        <h5>Email:</h5>
        <input type="text" name="email" defaultValue={ this.state.data[0].email } onChange={e => this.onChange(e)} />
        <h5>Title:</h5>
        <input type="text" name="title" defaultValue={ this.state.data[0].title } onChange={e => this.onChange(e)} />
        <h5>Description:</h5>
        <input type="text" name="longTitle" defaultValue={ this.state.data[0].longTitle } onChange={e => this.onChange(e)} />
        <h2 className="center" >Intro:</h2>
        <div className="center"><img src={require('../img/orn.png')} alt="" className="orn"/></div>
        <h5>Title:</h5>
        <input type="text" name="introTitle" defaultValue={ this.state.data[0].introTitle } onChange={e => this.onChange(e)} />
        <h5>Description:</h5>
        <input type="text" name="introLongTitle" defaultValue={ this.state.data[0].introLongTitle } onChange={e => this.onChange(e)} />
        <h5>Link to video:</h5>
        <input type="text" name="videoLink" defaultValue={ this.state.data[0].videoLink } onChange={e => this.onChange(e)} />        
        <h5>Text:</h5>
        <textarea name="introText" id="" cols="30" rows="10" defaultValue={ this.state.data[0].introText } onChange={e => this.onChange(e)}></textarea>
        <button type="submit" className="btn-large waves-effect waves-light xbutton">Save</button>
      </form>
    );
  }
}

export default Misc;

3 个答案:

答案 0 :(得分:1)

通过查看this.setState({ value: e.target.value });,输入的每次更改都会为唯一覆盖先前值的state.value属性设置一个新值。

我认为您应该将onChange修改为

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

提交后,您的handleSubmit中的值将为:

const data = {
  phone: this.state.phone,
  email: this.state.email, 
  title: this.state.title,
 // same for other inputs .. 
};

这将以与相应输入同名的状态更新属性。

答案 1 :(得分:0)

没关系! 这是工作代码。 要初始化正确的POST请求,我使用if运算符:

import React, { Component } from 'react';
import axios from 'axios';

class Misc extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      value: [],
      loading: true,
      error: false,
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  onChange(e) {
    this.setState({ [e.target.name]: e.target.value })
  }
  componentDidMount() {
    axios.get('http://localhost:5555/data')
      .then(res => {
        const data = res.data.data; // get the data array instead of object
        this.setState({ data, loading: false });
      })
      .catch(err => { // log request error and prevent access to undefined state
        this.setState({ loading: false, error: true });
        console.error(err);
      })
  }
  handleSubmit(e) {
    e.preventDefault();

    const data = {
      phone: this.state.phone ? this.state.phone : this.state.data[0].phone,
      email: this.state.email ? this.state.email : this.state.data[0].email,
      title: this.state.title ? this.state.title : this.state.data[0].title,
      longTitle: this.state.longTitle ? this.state.longTitle : this.state.data[0].longTitle,
      introTitle: this.state.introTitle ? this.state.introTitle : this.state.data[0].introTitle,
      introLongTitle: this.state.introLongTitle ? this.state.introLongTitle : this.state.data[0].introLongTitle,
      videoLink: this.state.videoLink ? this.state.videoLink : this.state.data[0].videoLink,
      introText: this.state.introText ? this.state.introText : this.state.data[0].introText
    };

    //console.log(this.state.phone);

    axios.post('http://localhost:5555/data', { data })
      .then(res => {
        console.log(data);
        console.log(this.state.data[0]);
      })
  }
  render() {
    if (this.state.loading) {
      return (
        <div>
          <p> Loading... </p>
        </div>
      )
    }
    if (this.state.error || !this.state.data[0]) { // if request failed or data is empty don't try to access it either
      return (
        <div>
          <p> An error occured </p>
        </div>
      )
    }
    return (
      <form action="" onSubmit={this.handleSubmit}>
        <h2 className="center" >Изменить данные</h2>
        <div className="center"><img src={require('../img/orn.png')} alt="" className="orn" /></div>
        <h5>Phone:</h5>
        <input type="text" name="phone" defaultValue={this.state.data[0].phone} onChange={e => this.onChange(e)} />
        <h5>Email:</h5>
        <input type="text" name="email" defaultValue={this.state.data[0].email} onChange={e => this.onChange(e)} />
        <h5>Title:</h5>
        <input type="text" name="title" defaultValue={this.state.data[0].title} onChange={e => this.onChange(e)} />
        <h5>Description:</h5>
        <input type="text" name="longTitle" defaultValue={this.state.data[0].longTitle} onChange={e => this.onChange(e)} />
        <h2 className="center" >Intro:</h2>
        <div className="center"><img src={require('../img/orn.png')} alt="" className="orn" /></div>
        <h5>Title:</h5>
        <input type="text" name="introTitle" defaultValue={this.state.data[0].introTitle} onChange={e => this.onChange(e)} />
        <h5>Description:</h5>
        <input type="text" name="introLongTitle" defaultValue={this.state.data[0].introLongTitle} onChange={e => this.onChange(e)} />
        <h5>Link to video:</h5>
        <input type="text" name="videoLink" defaultValue={this.state.data[0].videoLink} onChange={e => this.onChange(e)} />
        <h5>Text:</h5>
        <textarea name="introText" id="" cols="30" rows="10" defaultValue={this.state.data[0].introText} onChange={e => this.onChange(e)}></textarea>
        <button type="submit" className="btn-large waves-effect waves-light xbutton">Save</button>
      </form>
    );
  }
}

export default Misc;

答案 2 :(得分:0)

我建议您使用FormData来保持所有表单数据的干净和可迭代性,一旦提交表单,数据就会进入事件提交并变得更易于使用。

使用 FormData API

    const formData = new FormData(event.target)

这样,创建要使用的对象变得更加容易和清洁。

  

formData返回并且FormData对象是可迭代的。

    const body = {}
    formData.forEach((value, property) => body[property] = value)

因此,既然您已经建立了一个新对象,就可以更新,删除,添加,加密或随意使用它的属性和/或值。

另外,由于 HTML是为您本地提供的,也不需要使用函数来处理输入的更改,只需使用onChange和{{ 1}}致力于使您的输入内容填写在您的所有字段中。

  

有时候HTML足以满足我们想要的工作了:)

这是上述所有内容的一个小例子。

defaultValue=""
  

如果您想了解更多有关如何处理React中的错误的信息,请查看Error Boundaries