使用ReactJS上的axios选择输入返回未定义的

时间:2018-07-30 14:40:44

标签: javascript reactjs input axios react-select

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

请问该如何解决?

1 个答案:

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