У меня есть выбор ввода, разработанный с помощью responseJS, параметры которого представляют собой имена категорий (получаемые из категорий таблиц) с использованием nodejs и MySQL.
Мой роутер:
exports.ajouterprod = function(req, res) {
upload(req, res, function(imageUploadErr) {
console.info("req", req.body);
var today = new Date();
var produits = {
"Nomcat": req.body.Nomcat,
"Img": imge
}
console.info("Image : " + req.body.Img);
console.info(produits)
connection.query('INSERT INTO produits SET ?', produits, function(error, results, fields) {
if (error) {
console.info("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.info("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.info(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.
Как я могу это исправить?
@javed, когда я добавляю состояние и запускаю его, я получаю `Nomcat = \ '[объект-объект], [объект-объект], [объект-объект], [объект-объект] \' '
почему вы используете элемент ввода как select. если возможно, используйте элемент выбора html
Это все та же проблема! когда я выбрал, он все еще находится на <option value = "" hidden>Choisissez la catégorie</option> и возвращает Nomcat = \ '[объект-объект], [объект-объект], [объект-объект], [объект-объект] \'



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Сначала вы используете Nomcat для назначения всего объекта данных внутри вызова GET, затем вы используете значение select как value = {this.state.Nomcat}, которое даст вам объект Nomcat в качестве значения, а не сделанный вами выбор. Кроме того, на самом деле нет никакого способа получить это значение, поскольку вы не определили onChange нигде в своем выборе.
Фактически, вы можете получить это значение напрямую, не используя onChange внутри onSubmit вашей формы. Но опять же, вы не используете полученные FormData (Неконтролируемый способ). Вы получаете данные из штата (контролируемый способ)
В основном вы смешиваете контролируемые и неконтролируемые компоненты, и есть много вещей, которые нужно изучить и исправить.
Подробнее здесь - https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
Затем, чтобы сначала отладить проблему, вам нужно четко понимать, находится ли она во внешней или внутренней части. Изолируйте это!
Если сервер дает правильный ответ, вы, вероятно, должны увидеть результаты вызова GET на вкладке сети инструментов Dev. Погуглите, если вы не знаете об этом.
Как только он будет проверен, загляните только в свой интерфейс или серверную часть.
ОБНОВИТЬ -
Здесь мы переходим к простому, но законченному компоненту, демонстрирующему функциональность выбранного компонента. Просто помните, что это контролируемый способ решения проблем, и на данный момент это должен быть лучший способ начать работу.
Вы можете поиграть с тем же кодом здесь - 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.handleChangeEvent}>
<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
});
}
handleChangeEvent = e => {
console.info(e.target.value);
this.setState({ selectedNomcat: e.target.value });
};
handleSubmit = e => {
e.preventDefault();
console.info("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 и другие элементы формы. Добавление ШАГА ЗА ШАГОМ поможет вам узнать, где ваш код сломался.
На самом деле избегайте FormData, поскольку она имеет ограниченную поддержку браузером.
Спасибо @Kushalvm, когда я запускаю свой бэкэнд с Postman, он работает хорошо, но это проблема моего интерфейса.
Я добавляю onChange в <Input type = "select" name = "selectcat" id = "selectcat" onChange = {this.handleNomcatChange} >, и когда я запускаю его и выбираю категорию, я получаю TypeError: this.state.Nomcat.map is not a function
@CodeLover Я обновил свой ответ, включив в него базовый компонент для выбора
Я попробую этот @Kushalvm, и взгляните, пожалуйста, здесь stackoverflow.com/questions/51600494/… Я использовал formData, потому что у меня есть загруженное изображение в мою форму.
Нет необходимости, просто просмотрите мою реализацию того, как я назначил переменные значения и состояния для выбора, и вы поймете, почему вы получаете объект вместо строки. Примите ответ, если это помогло.
Это все та же проблема, он возвращает Object.
Вы проверяли ссылку на песочницу, которой я поделился, и наблюдали, что там console.infos?
formData.append ('Nomcat', this.state.Nomcat); вы пропустили добавление состояния между этим и Nomcat.