Select 输入 returns 在 ReactJS 上使用 axios 未定义
Select input returns undefined using axios on ReactJS
我有一个使用 reactJS 开发的 select 输入,其中选项是使用 nodejs 和 MySQL.
的类别名称(来自 table 类别)
我的路由器:
exports.ajouterprod = function(req, res) {
upload(req, res, function(imageUploadErr) {
console.log("req", req.body);
var today = new Date();
var produits = {
"Nomcat": req.body.Nomcat,
"Img": imge
}
console.log("Image : " + req.body.Img);
console.log(produits)
connection.query('INSERT INTO produits SET ?', produits, function(error, results, fields) {
if (error) {
console.log("error ocurred", error);
res.send({
"code": 400,
"failed": "error ocurred"
})
}
else {
res.send({
"code": 200,
"success": "produit registered sucessfully"
});
}
})
});
};
我的class:
class AjouterProduit extends Component {
constructor(props) {
super(props)
this.state = {
Nomcat: [],
Img: "",
FormData :"",
};
this.handleSubmit = this.handleSubmit.bind(this);
}
componentWillReceiveProps(nextProps) {
console.log("nextProps", nextProps);
}
componentDidMount() {
axios({
method: "get",
url: "/app/getcat/",
withCredentials: true,
}).then(response => {
if (response && response.data) {
this.setState({
Nomcat: response.data
});
}
}).catch(error => console.log(error));
}
handleSubmit() {
const formData = new FormData();
formData.append('Nomcat', this.Nomcat);
formData.append('Img', this.state.Img);
axios({
method: 'post',
url: '/app/ajouterprod/',
data: formData,
withCredentials: true,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(function(response) {
this.setState({
alert: null
});
this.props.history.push('/produits/listeproduits')
}.bind(this))
}
handleNomcatChange = (e) => {
this.setState({
Nomcat: e.target.value
});
}
handleImgChange = (e) => {
this.setState({
Img: e.target.files[0]
});
}
render() {
let {Nomcat} = this.state.Nomcat;
return (<div className="animated fadeIn">
<Row>
<Col xs="12" >
<Card>
<CardHeader>
<h4><strong> <i className="fa fa-cube"> </i> Ajouter un nouveau produit</strong></h4>
</CardHeader>
<CardBody>
<Form className="form-horizontal" method="POST" encType="multipart/form-data" >
<FormGroup row>
<Col md="3">
<h5> <Label htmlFor="hf-nom"><strong>Catégorie</strong></Label></h5>
</Col>
<Col xs="12" md="9">
<Input type="select" name="selectcat" id="selectcat" value={this.state.Nomcat} >
<option value="" hidden>Choisissez la catégorie</option>
<option value="0" ></option>
{ this.state.Nomcat.map((cat) => <option value={cat} key={cat.Nomcat}>{cat.Nomcat}</option>)
}
</Input>
</Col>
</FormGroup>
<FormGroup row>
<Col md="3">
<h5> <Label htmlFor="file-input"><strong>Image produit</strong></Label></h5>
</Col>
<Col xs="12" md="9">
<Input type="file" id="file-input" name="file-input" onChange={this.handleImgChange} />
</Col>
</FormGroup>
当我 运行 它在我的前端时,如您所见:
当我选择类别时,它没有被 select 编辑,它仍然在 <option value="" hidden>Choisissez la catégorie</option>
上,当我提交表单时,它会被插入 table 但Nomcat 有 undefined
值。
请问我该如何解决?
您首先使用 Nomcat
在 GET 调用中分配整个数据对象,然后您使用 select 的值作为 value={this.state.Nomcat}
,这将为您提供对象 Nomcat
作为价值,而不是你创造的 selection。最重要的是,实际上没有办法获得该值,因为您没有在 select.
的任何地方定义 onChange
事实上,您可以直接获取该值,而无需在表单的 onSubmit 中使用 onChange
。但是话又说回来,您没有使用您获得的 FormData( Uncontrolled way )。您正在从状态(受控方式)
获取
基本上你是在混合受控和非受控组件,那里有很多东西需要学习和修复。
在此处阅读更多内容 - https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
那么先调试问题,你要分清楚是前端还是后端。隔离它!
如果服务器给出了正确的响应,那么您应该可以在开发工具的网络选项卡中看到 GET 调用的结果。 Google 如果你不知道的话。
验证通过后,只查看您各自的前端或后端。
更新 -
这里我们使用一个简单但完整的组件来演示 select 组件的功能。
请记住,这是一种受控的处理方式,它应该是目前开始工作的最佳方式。
您可以在这里使用相同的代码 - https://codesandbox.io/s/rm130zylkp
import React, { Component } from "react";
class FormComponent extends Component {
constructor(props) {
super(props);
this.state = {
nomcat: []
};
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<select name="selectedNomcat" value={this.state.selectedNomcat} onChange={this.handleChange}>
<option key={-1}> Select a value</option>
{(this.state.nomcat || []).map((item, i) => (
<option key={i}>{item.a}</option>
))}
</select>
<input type="submit" value="Submit" />
</form>
);
}
componentDidMount() {
// API call here
// Assume
const data = [{ a: 1 }, { a: 2 }, { a: 3 }];
this.setState({
nomcat: data
});
}
handleChange = e => {
console.log(e.target.value);
this.setState({ selectedNomcat: e.target.value });
};
handleSubmit = e => {
e.preventDefault();
console.log("selectedNomcat", this.state.selectedNomcat);
const { selectedNomcat, whateverValue} = this.state;
const payload = {
param1: selectedNomcat,
param2: whateverValue,
}
// POST call here
// axios.post('/address', payload).then(res => {
// // Whatever
// });
};
}
export default FormComponent;
每当您想使用 onChange 事件处理程序中的任何值时,简单的规则是它应该设置为正确的状态变量,然后您应该实际使用该状态来获取表单元素的值,就像我在 handleSubmit
。
获取 FormData() 形式的值是不受控制的做事方式,但我们不会深入研究并从您的组件中完全删除该代码。事实上,我建议使用我的代码版本并逐步添加 API 调用和其他表单元素。添加 STEP BY STEP 将帮助您了解代码在哪里出错。
事实上,请避免使用 FormData,因为它的浏览器支持有限。
我有一个使用 reactJS 开发的 select 输入,其中选项是使用 nodejs 和 MySQL.
的类别名称(来自 table 类别)我的路由器:
exports.ajouterprod = function(req, res) {
upload(req, res, function(imageUploadErr) {
console.log("req", req.body);
var today = new Date();
var produits = {
"Nomcat": req.body.Nomcat,
"Img": imge
}
console.log("Image : " + req.body.Img);
console.log(produits)
connection.query('INSERT INTO produits SET ?', produits, function(error, results, fields) {
if (error) {
console.log("error ocurred", error);
res.send({
"code": 400,
"failed": "error ocurred"
})
}
else {
res.send({
"code": 200,
"success": "produit registered sucessfully"
});
}
})
});
};
我的class:
class AjouterProduit extends Component {
constructor(props) {
super(props)
this.state = {
Nomcat: [],
Img: "",
FormData :"",
};
this.handleSubmit = this.handleSubmit.bind(this);
}
componentWillReceiveProps(nextProps) {
console.log("nextProps", nextProps);
}
componentDidMount() {
axios({
method: "get",
url: "/app/getcat/",
withCredentials: true,
}).then(response => {
if (response && response.data) {
this.setState({
Nomcat: response.data
});
}
}).catch(error => console.log(error));
}
handleSubmit() {
const formData = new FormData();
formData.append('Nomcat', this.Nomcat);
formData.append('Img', this.state.Img);
axios({
method: 'post',
url: '/app/ajouterprod/',
data: formData,
withCredentials: true,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(function(response) {
this.setState({
alert: null
});
this.props.history.push('/produits/listeproduits')
}.bind(this))
}
handleNomcatChange = (e) => {
this.setState({
Nomcat: e.target.value
});
}
handleImgChange = (e) => {
this.setState({
Img: e.target.files[0]
});
}
render() {
let {Nomcat} = this.state.Nomcat;
return (<div className="animated fadeIn">
<Row>
<Col xs="12" >
<Card>
<CardHeader>
<h4><strong> <i className="fa fa-cube"> </i> Ajouter un nouveau produit</strong></h4>
</CardHeader>
<CardBody>
<Form className="form-horizontal" method="POST" encType="multipart/form-data" >
<FormGroup row>
<Col md="3">
<h5> <Label htmlFor="hf-nom"><strong>Catégorie</strong></Label></h5>
</Col>
<Col xs="12" md="9">
<Input type="select" name="selectcat" id="selectcat" value={this.state.Nomcat} >
<option value="" hidden>Choisissez la catégorie</option>
<option value="0" ></option>
{ this.state.Nomcat.map((cat) => <option value={cat} key={cat.Nomcat}>{cat.Nomcat}</option>)
}
</Input>
</Col>
</FormGroup>
<FormGroup row>
<Col md="3">
<h5> <Label htmlFor="file-input"><strong>Image produit</strong></Label></h5>
</Col>
<Col xs="12" md="9">
<Input type="file" id="file-input" name="file-input" onChange={this.handleImgChange} />
</Col>
</FormGroup>
当我 运行 它在我的前端时,如您所见:
当我选择类别时,它没有被 select 编辑,它仍然在 <option value="" hidden>Choisissez la catégorie</option>
上,当我提交表单时,它会被插入 table 但Nomcat 有 undefined
值。
请问我该如何解决?
您首先使用 Nomcat
在 GET 调用中分配整个数据对象,然后您使用 select 的值作为 value={this.state.Nomcat}
,这将为您提供对象 Nomcat
作为价值,而不是你创造的 selection。最重要的是,实际上没有办法获得该值,因为您没有在 select.
的任何地方定义 onChange
事实上,您可以直接获取该值,而无需在表单的 onSubmit 中使用 onChange
。但是话又说回来,您没有使用您获得的 FormData( Uncontrolled way )。您正在从状态(受控方式)
基本上你是在混合受控和非受控组件,那里有很多东西需要学习和修复。
在此处阅读更多内容 - https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
那么先调试问题,你要分清楚是前端还是后端。隔离它!
如果服务器给出了正确的响应,那么您应该可以在开发工具的网络选项卡中看到 GET 调用的结果。 Google 如果你不知道的话。
验证通过后,只查看您各自的前端或后端。
更新 -
这里我们使用一个简单但完整的组件来演示 select 组件的功能。 请记住,这是一种受控的处理方式,它应该是目前开始工作的最佳方式。
您可以在这里使用相同的代码 - https://codesandbox.io/s/rm130zylkp
import React, { Component } from "react";
class FormComponent extends Component {
constructor(props) {
super(props);
this.state = {
nomcat: []
};
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<select name="selectedNomcat" value={this.state.selectedNomcat} onChange={this.handleChange}>
<option key={-1}> Select a value</option>
{(this.state.nomcat || []).map((item, i) => (
<option key={i}>{item.a}</option>
))}
</select>
<input type="submit" value="Submit" />
</form>
);
}
componentDidMount() {
// API call here
// Assume
const data = [{ a: 1 }, { a: 2 }, { a: 3 }];
this.setState({
nomcat: data
});
}
handleChange = e => {
console.log(e.target.value);
this.setState({ selectedNomcat: e.target.value });
};
handleSubmit = e => {
e.preventDefault();
console.log("selectedNomcat", this.state.selectedNomcat);
const { selectedNomcat, whateverValue} = this.state;
const payload = {
param1: selectedNomcat,
param2: whateverValue,
}
// POST call here
// axios.post('/address', payload).then(res => {
// // Whatever
// });
};
}
export default FormComponent;
每当您想使用 onChange 事件处理程序中的任何值时,简单的规则是它应该设置为正确的状态变量,然后您应该实际使用该状态来获取表单元素的值,就像我在 handleSubmit
。
获取 FormData() 形式的值是不受控制的做事方式,但我们不会深入研究并从您的组件中完全删除该代码。事实上,我建议使用我的代码版本并逐步添加 API 调用和其他表单元素。添加 STEP BY STEP 将帮助您了解代码在哪里出错。
事实上,请避免使用 FormData,因为它的浏览器支持有限。