【问题标题】:Select input returns undefined using axios on ReactJS在 ReactJS 上使用 axios 选择输入返回未定义
【发布时间】:2018-07-30 14:40:43
【问题描述】:

我有一个使用 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>

当我在前端运行它时,如您所见:

当我选择类别时,它没有被选择,它仍然在&lt;option value="" hidden&gt;Choisissez la catégorie&lt;/option&gt;上,当我提交表单时,它将被插入到表格中但Nomcat有undefined值。

请问我该如何解决?

【问题讨论】:

  • formData.append('Nomcat', this.state.Nomcat);你错过了在 this 和 Nomcat 之间添加状态。
  • @javed 当我添加状态并运行它时,我得到`Nomcat = \'[object Object],[object Object],[object Object],[object Object]\' `
  • 为什么使用输入元素作为选择。如果可能的话,请使用 html 选择元素
  • 还是一样的问题!当我选择时,它仍然在&lt;option value="" hidden&gt;Choisissez la catégorie&lt;/option&gt; 上并返回Nomcat = \'[object Object],[object Object],[object Object],[object Object]\'

标签: javascript reactjs input axios react-select


【解决方案1】:

您首先使用 Nomcat 在 GET 调用中分配整个数据对象,然后您将 select 的值用作 value={this.state.Nomcat} ,这将为您提供对象 Nomcat 作为值,而不是您所做的选择。最重要的是,实际上没有办法获得该值,因为您尚未在选择的任何地方定义 onChange
事实上,您可以直接获取该值,而无需在表单的 onSubmit 中使用onChange。但话又说回来,你没有使用你得到的 FormData(Uncontrolled way)。您正在从状态中获取(受控方式

基本上,您正在混合受控和不受控的组件,并且有很多东西需要学习和修复。

在此处阅读更多信息 - https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/

那么首先调试问题,你需要非常清楚它是在前端还是后端。隔离它!

如果服务器给出正确的响应,那么您应该会在开发工具的网络选项卡中看到 GET 调用的结果。如果您不知道,请谷歌。

验证后,只需查看您各自的前端或后端。

更新 -

这里我们使用一个简单而完整的组件来演示选择组件的功能。 请记住,这是一种受控的处理方式,它应该是目前开始的最佳方式。

您可以在这里使用相同的代码 - 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,因为它对浏览器的支持有限。

【讨论】:

  • 谢谢@Kushalvm,当我使用 Postman 运行后端时,它运行良好,但这是我前端的问题。
  • 我将 onChange 添加到 &lt;Input type="select" name="selectcat" id="selectcat" onChange={this.handleNomcatChange} &gt;,当我运行它并选择类别时,我得到 TypeError: this.state.Nomcat.map is not a function
  • @CodeLover 我已经更新了我的答案以包含一个用于选择的基本组件
  • 我会试试@Kushalvm,请看这里stackoverflow.com/questions/51600494/… 我使用了formData,因为我在表单上上传了图片。
  • 您是否检查了我共享的沙盒链接并观察了它的 console.logs 内容?
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
相关资源
最近更新 更多