带有 Reactjs 的 Axios 发布表单

Posted

技术标签:

【中文标题】带有 Reactjs 的 Axios 发布表单【英文标题】:Axios Post Form with Reactjs 【发布时间】:2018-11-10 02:13:54 【问题描述】:

所以我在 Axios 上有这个 post 方法,如果我提交这个,它说

未捕获(承诺中)错误:网络错误 在 createError (createError.js:16) 在 XMLHttpRequest.handleError (xhr.js:87)

如果我使用这种方法:

axios.post('http://localhost:5000/users', (userid: this.state.userid)

它有效。但是,如果我在 axios 帖子中添加 2 个或更多 arg,它会再次出错:

axios.post('http://localhost:5000/users', (userid: this.state.userid, fullname: this.state.fullname ))

这是我的完整代码。如您所见,我尝试了不同的代码组合,并且仅在我仅传递 1 个 arg 时才有效。

import React from 'react';
import axios from 'axios';
// import  Form  from 'antd';
// import  List, Card, Form  from 'antd';

export default class FormUser extends React.Component 
    // constructor(props) 
    //   super(props)
    //   this.state = 
      state = 
        userid: '',
        fullname: '',
        usergroup:'',
        emailid: '',
        mobile: '',
        title: '',

  ;

  handleChange = event => 
    this.setState( userid: event.target.value );
    this.setState( fullname: event.target.value );
    this.setState( usergroup: event.target.value );
    this.setState( emailid: event.target.value );
    this.setState( mobile: event.target.value );
    this.setState( title: event.target.value );
  

  handleSubmit = event => 
    event.preventDefault();

    // const userform = userid: this.state.userid;
    // const fullnameForm = fullname: this.state.fullname;
    // const usergroupForm = usergroup: this.state.usergroup;
    // const emailidForm = emailid: this.state.emailid;
    // const mobileForm = mobile: this.state.mobile;
    // const titleForm = title: this.state.title;

    axios.post('http://localhost:5000/users', (userid: this.state.userid, fullname: this.state.fullname )) 
    //  userid: this.state.userid, fullname: this.state.fullname , usergroup: this.state.usergroup, emailid: this.state.emailid, mobile: this.state.mobile, title: this.state.title ) 
    //  userform, fullnameForm, usergroupForm, emailidForm, mobileForm, titleForm ) 
      .then(res => 
        console.log(res);
        console.log(res.data);
      )
  

  render() 
    return (
      <form onSubmit=this.handleSubmit>
        <label>User Project ID:  <input type="text" name="userid" onChange=this.handleChange/></label><br/>
        <label>Full Name:  <input type="text" name="fullname" onChange=this.handleChange/></label><br/>
        <label>User Group:  <input type="text" name="usergroup" onChange=this.handleChange/></label><br/>
        <label>Email:  <input type="text" name="emailid" onChange=this.handleChange/></label><br/>
        <label>Mobile:  <input type="text" name="mobile" onChange=this.handleChange/></label><br/>
        <label>Title:  <input type="text" name="title" onChange=this.handleChange/></label>
        <button type="submit">Add</button>
      </form>
    )
  

Express 上的 AXIOS POST

app.post('/users', function (req, res) 
  var postData = req.body;
  // postData.created_at = new Date();
  connection.query("INSERT INTO users SET ?", postData, function (error, results, fields) 
    if (error) throw error;
    console.log(results.insertId);
    res.end(JSON.stringify(results));
  );
);

【问题讨论】:

与实际问题无关,但使用这样的handleChange 处理程序,您的所有状态字段最终都将具有相同的值。此外,由于 没有 value 属性,因此它们不受控制,这可能不是您想要的。 我应该改成这个吗? 我建议(重新)阅读表单上的 React 文档。 reactjs.org/docs/forms.html 【参考方案1】:

每个状态的事件处理程序。有什么办法可以做得更好吗? 是的,它会像这样工作

import React,  Component  from 'react';

class UserForm extends Component 
  constructor() 
    super();
    this.state = 
      fname: '',
      lname: '',
      email: '',
    ;
  

  onChange = (e) => 
    /*
      Because we named the inputs to match their
      corresponding values in state, it's
      super easy to update the state
    */
    this.setState( [e.target.name]: e.target.value );
  

  render() 
    const  fname, lname, email  = this.state;
    return (
      <form>
        <input
          type="text"
          name="fname"
          value=fname
          onChange=this.onChange
        />
        <input
          type="text"
          name="lname"
          value=lname
          onChange=this.onChange
        />
        <input
          type="text"
          name="email"
          value=email
          onChange=this.onChange
        />
      </form>
    );
  

关于提交表单,您的 axios 帖子会像这样工作

onSubmit = (e) => 
    e.preventDefault();
    // get our form data out of state
    const  fname, lname, email  = this.state;

    axios.post('/',  fname, lname, email )
      .then((result) => 
        //access the results here....
      );
  

【讨论】:

【参考方案2】:

axios.post(url[, data[, config]]) 的第三个参数是 Axios 配置对象,你无意中传入的

axios.post('http://localhost:5000/users', (userid: this.state.userid, fullname: this.state.fullname ))

所以请求被错误配置并且不起作用。

相反,要 POST 的所有数据都应该在单个 data 对象中。

axios.post('http://localhost:5000/users', 
  userid: this.state.userid,
  fullname: this.state.fullname,
)

【讨论】:

那么localhost:5000 的 POST 有什么东西在听吗?你的 React 应用程序也在 localhost:5000 上吗?如果它们来自不同的来源,则需要设置 CORS,以便 React 应用可以与后端通信。 是的,我已经设置并运行了 cors。 Express 为 8000。正如我之前所说,单个帖子数据有效,但如果有 2 个或更多数据则无效。如何将状态更改为对象数组?这可能吗? 查看浏览器控制台中的“网络”选项卡,了解实际发送的有效负载是什么以及实际的网络错误是什么。它可能是您应用中的 400 或 500。 如果我发布 2 条数据,它会显示 Access-Control-Request-Headers: content type 和下面的 Access-Control-Method: POST。如果发布单个数据,则会有包含数据的控制台日志。 所以我才注意到单条数据实际上是记录到数据库中的,其他字段都是空的。【参考方案3】:

所以显然我必须为每个状态添加事件处理程序。有什么办法可以做得更好吗?

import React from 'react';
import axios from 'axios';
import  Form  from 'antd';
// import  List, Card, Form  from 'antd';

const FormItem = Form.Item;

export default class FormUser extends React.Component 
  // constructor(props) 
  //   super(props)
  //   this.state = 
  state = 
    userid: '',
    fullname: '',
    usergroup: '',
    emailid: '',
    mobile: '',
    title: '',

  ;

  handleUserIDChange = event => this.setState( userid: event.target.value )
  handleFullNameChange = event => this.setState( fullname: event.target.value )
  handleUserGroupChange = event => this.setState( usergroup: event.target.value )
  handleEmailIDChange = event => this.setState( emailid: event.target.value )
  handleMobileChange = event => this.setState( mobile: event.target.value )
  handleTitleChange = event => this.setState( title: event.target.value )

  handleSubmit = event => 
    event.preventDefault();

    // const userform = userid: this.state.userid;
    // const fullnameForm = fullname: this.state.fullname;
    // const usergroupForm = usergroup: this.state.usergroup;
    // const emailidForm = emailid: this.state.emailid;
    // const mobileForm = mobile: this.state.mobile;
    // const titleForm = title: this.state.title;

    axios.post('http://localhost:5000/users',
       userid: this.state.userid, fullname: this.state.fullname, usergroup: this.state.usergroup, emailid: this.state.emailid, mobile: this.state.mobile, title: this.state.title ,)
      .then(res => 
        console.log(res);
        console.log(res.data);
      )
  

  render() 
    return (

      // const formItemLayout = 
      //   labelCol: 
      //     xs:  span: 24 ,
      //     sm:  span: 8 ,
      //   ,
      //   wrapperCol: 
      //     xs:  span: 24 ,
      //     sm:  span: 16,
      //   ,
      // ;

      <Form onSubmit=this.handleSubmit>
        <FormItem>
          <label>User Project ID:  <input type="text" name="this.state.userid" onChange=this.handleUserIDChange /></label>
        </FormItem>
        <FormItem>
          <label>Full Name:  <input type="text" name="this.state.fullname" onChange=this.handleFullNameChange /></label><br />
        </FormItem>
        <FormItem>
          <label>User Group:  <input type="text" name="this.state.usergroup" onChange=this.handleUserGroupChange /></label><br />
        </FormItem>
        <FormItem>
          <label>Email:  <input type="text" name="this.state.emailid" onChange=this.handleEmailIDChange /></label>
        </FormItem>
        <FormItem>
          <label>Mobile:  <input type="text" name="this.state.mobile" onChange=this.handleMobileChange /></label>
        </FormItem>
        <FormItem>
          <label>Title:  <input type="text" name="this.state.title" onChange=this.handleTitleChange /></label>
        </FormItem>
        <button type="submit">Add</button>
      </Form>
    )
  

【讨论】:

以上是关于带有 Reactjs 的 Axios 发布表单的主要内容,如果未能解决你的问题,请参考以下文章

使用 axios 和 ReactJS 进行反应选择后如何获取数据?

ReactJS AXIOS 帖子不起作用

ReactJS - setState Axios POST 响应

axios 为带有表单数据的发布请求返回 404

带有 ReactJS 的 Django 表单

reactjs:使用 reactstrap ui 的带有数据时间选择器的 formik 表单示例