[英]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.