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,因为它的浏览器支持有限。