簡體   English   中英

如何使用axios從React表單發送POST請求?

[英]How to send POST request from React form using 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;

通過查看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 .. 
};

這將以與相應輸入同名的狀態更新屬性。

我建議使用FormData來保持所有表單數據的干凈和可迭代性,一旦提交表單,數據就會進入事件提交並且變得更易於使用。

使用FormData API

    const formData = new FormData(event.target)

這樣,創建要使用的對象變得更加容易和清潔。

formData返回並且FormData對象是可迭代的。

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

因此,既然您已經構建了一個新對象,就可以更新,刪除,添加,加密或隨意使用它的屬性和/或值。

同樣,也不需要使用函數使用onChange方法來處理輸入的更改,因為HTML本身就是為您完成的 ,只需使用defaultValue=""並使用required屬性來將輸入保留在所有字段中。

有時候HTML足以滿足我們想要的工作了:)

這是上述所有內容的一個小例子。

import React from 'react';

export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      //no needed.
    }
  }

  onSubmitForm = e => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const body = {}
    formData.forEach((value, property) => body[property] = value)
    //here you can update, remove, add values/properties in the body object this is specially usefull if any custom process must be done to check, encrypt data or wherever you want.
    console.table(body)
    // Request goes here.
  }

  render() {
    return (
      <div className="App">
        <form onSubmit={e => this.onSubmitForm(e)}>
          <input name="name" type="text" defaultValue="" required />
          <input name="lastname" type="text" defaultValue="" required />
          <button type="submit">submit</button>
        </form>
      </div>
    )
  }
}

如果您想了解更多有關如何在React中處理錯誤的信息,請查看Error Boundaries

沒關系! 這是工作代碼。 要初始化正確的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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM