我有一个用reactJS开发的选择输入,其中的选项是使用nodejs和MySQL的类别名称(从表类别中获取)。
我的路由器:
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 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>
当我在前端运行它时,您会看到:
当我选择类别时,它尚未被选择并且仍在<option value="" hidden>Choisissez la catégorie</option>
上,当我提交表单时,它将被插入表中,但是Nomcat的值为undefined
。
请问该如何解决?
答案 0 :(得分:1)
您首先使用Nomcat
在GET调用中分配整个数据对象,然后使用select作为value={this.state.Nomcat}
的值,这将为您提供对象Nomcat
的值,而不是您所做的选择。最重要的是,实际上您无法获得该值,因为您尚未在选择的任何位置定义onChange
。
实际上,您可以直接获取该值,而无需在表单的onSubmit中使用onChange
。但是话又说回来,您并没有利用所获得的FormData(不受控制的方式)。您正在从状态(受控方式)
基本上,您是在混合控制和不受控制的组件,在那里有很多东西需要学习和修复。
在此处了解更多-https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
然后首先调试问题,您需要真正弄清它是在前端还是后端。隔离吧!
如果服务器给出正确的响应,则您可能应该在Dev工具的“网络”选项卡中看到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事件处理程序中的任何值时,简单的规则就是应将其设置为正确的状态变量,然后您应像在{{1中所做的那样,实际使用该状态来获取表单元素的值。 }}。
以FormData()的形式获取值是不受控制的处理方式,但是我们不打算这样做,而是从您的组件中完全删除该代码。实际上,我建议使用我的代码版本,并使用STEP BY STEP添加API调用和其他表单元素。添加STEP BY STEP将有助于您了解代码在何处中断。
事实上,请避免使用FormData,因为它对浏览器的支持有限。