这就像使用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;
答案 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。