如何解决React-Bootstrap-Typeahead的错误

问题描述

我有一个名为ProductCard的子组件,该组件从名为CreateNewSales的父组件获取道具。 onChange函数带有两个参数,并在父级中定义。如果我在ProductCard中调用函数,尽管除数量输入之外的所有其他输入似乎都可以正常工作,但我仍会继续输入该错误。这是代码

这是产品卡:

import React,{ useState,Fragment } from 'react';
import { FormGroup,Label,Input,Col} from 'reactstrap';
import { Typeahead } from 'react-bootstrap-typeahead';
import PropTypes from 'prop-types';

import {PlusSquare,MinusSquare} from 'react-feather'
const plusSquare = <PlusSquare/>
const minusSquare = <MinusSquare/>


const ProductCard = (props) => {

  console.log(props)

  const ProductOptions = [{id:1,name: "Clothes"},{id:2,name:"Services"},{id:3,name:"Shows"},{id:4,name: "Peace"}] //dummy date  //res_data.payload.data.product

  // const [singleSelections,setSingleSelections] = useState([]);
  // from quantityIncrement.js
  const [count,setCount] = useState(1)

  const decrement = () => {
    if(count === 1){
      setCount(count)
    } else{
      setCount(count-1)
    }
  };

  const increment = () => {
    setCount(count+1)
  };

  return(
    <Fragment>
      <FormGroup>
        <Label>Product Name</Label>
        <Typeahead
          id="basic-typeahead"
          labelKey="name"
          onChange={(e) => props.handleChange(e,props.index)}
          // onInputChange={props.setProductName}
          options={ProductOptions}
          name={ProductOptions}
          selected={props.value.productName}
          style={{backgroundColor:"#d5deee"}}
          value={props.value.productName}
        />
      </FormGroup>
      <FormGroup>
        <div className="form-row">
          <Col>
            <Label for="quantity">Quantity</Label>
            <div  style={{display: "flex"}}>
              <Input value={count} id="quantity" name="quantity" onChange={e=> setCount(e.target.value)} style={{backgroundColor: "#d5deee"}} />
              <div style={{display:"flex",marginTop:"5px"}}><span><i style={{ width: 15,fontSize: 10,padding: 11,color: '#848b97' }}  onClick={increment}>{plusSquare}</i></span><span><i style={{ width: 15,fontSize: 12,color: '#848b97' }} onClick={decrement}>{minusSquare}</i></span></div>
            </div>
          </Col>
          <Col>
            <Label for="discount">discount</Label>
            <Input type="text" id="discount" onChange = {(e) => props.handleChange(e,props.index)} value={props.value.discount} name="discount" style={{backgroundColor:"#d5deee"}} />
          </Col>
        </div>
      </FormGroup>
      <FormGroup>
        <div className="form-row">
          <Col>
            <Label for="price">Price</Label>
            <Input type="text" id="price" onChange={(e) => props.handleChange(e,props.index)} value={props.value.price} name="price" style={{backgroundColor:"#d5deee"}} />
          </Col>
          <Col>
            <Label for="amountPaid">Amount Paid</Label>
            <Input type="text" id="amountPaid" onChange={(e) => props.handleChange(e,props.index)} value={props.value.amountPaid} name="amountPaid" style={{backgroundColor:"#d5deee"}} />
          </Col>
        </div>
      </FormGroup>
    </Fragment>
  )
}

ProductCard.propTypes = {
  handleChange: PropTypes.func.isrequired,value: PropTypes.object.isrequired,// onClickQuantity: PropTypes.func.isrequired
}




export default ProductCard

这是CreateNewSale:

import React,{ Fragment,useState } from 'react';
import {Form,FormGroup,Card,Col,Row,CardBody,Button,ButtonGroup,Table} from 'reactstrap';
import {toast} from 'react-toastify';
import { Typeahead } from 'react-bootstrap-typeahead';
import { withRouter} from 'react-router';
// import {useHistory} from 'react-router-dom';
import {connect} from 'react-redux';

import {validateCreateNewSaleForm,responseErrorParser} from "../../components/authentication/validator"

// productCard.js

import ProductCard from '../../components/sales/ProductCard'

import {Trash2} from 'react-feather'
const trash2 = <Trash2/>

const CreateNewSale = (props) => {

  const [,setIsCreatingNewSale]  = useState(false)
  // const [singleSelections,setSingleSelections] = useState([]);

  // from the productCard.js 

  const [newProductValues,setNewProductValues] = useState([{
    productName: [],discount: "",price: "",amountPaid: "",quantity: "1",}]);

  // const [newProductName,setNewProductName] = useState([{
  //   newProductNames: [],//   newCustomerName: []
  // }])

  // const handleInputChange = (event) => {
  //   setNewProductName({
  //     ...newProductName,//     [event.target.name]: event.target.value
  //   });
  // }

  const [customerName,setCustomerName] = useState([])
  const [date,setDate] = useState('')
  const [dueDate,setDueDate] = useState('')
  const [vat,setVat] = useState('')
  // const [visible,setVisible] = useState(false)

  const handleChange = (event,index) => {
    console.log( event )
    const values = [...newProductValues];
    values[index][event.target.name] = event.target.value
    console.log('=======================>',values)
    setNewProductValues(values);
    // setNewProductValues({
    //   ...newProductValues,//   [event.target.name]: event.target.value
    // });
  }

  const handleAddFields = (e) => {
    setNewProductValues([...newProductValues,{discount:"",productName:[]
    }])
  }

  const handleRemoveFields = (index) => {
    const values  = [...newProductValues];
    values.splice(index,1);
    setNewProductValues(values);
  }

  const customerOptions = [{id: 1,name: "Olalekan"},{id: 2,name:"Michael"},{id: 3,name:"Emeka"},name: "Glory"}] //dummy data  //res_data.payload.data.customer

  const fields = {
    customer_name: { default: '',message: 'Please enter an already created customer name' },product_name: { default: '',quantity: { default: '',message: 'Please select a quantity' },discount: { default: '',message: 'Please enter the discount given' },price: { default: '',message: 'Please select the price given' },amount_paid: { default: '',message: 'Please enter the amount paid by the customer' },date: { default: '',message: 'Please enter date' },due_date: { default: '',message: 'Please enter due date given' },vat: { default: '',message: 'Please enter the vat' },}

  const handleCreateNewSale = async (e) => {
    e.preventDefault()
    setIsCreatingNewSale(true);
    const responsePayload = {
      customer_name: newProductValues.newCustomerName,//customerName
      product_name: newProductValues.newproductNames,quantity: newProductValues.quantity,discount: newProductValues.discount,price: newProductValues.price,amount_paid: newProductValues.amountPaid,date: date,due_date: dueDate,vat: vat
    }
    const errors = validateCreateNewSaleForm(responsePayload,fields)
    if (errors.isErrors) {
      setIsCreatingNewSale(false)
      setTimeout(() => {
          errors.errors.forEach(e => toast.error(e.message))
      },400);
    } else {
      const response = await props.CreateNewSale(responsePayload)
      if (response.status) {
        const newSale = response.payload.data.id
        localStorage.setItem('__grm__act__biz__',newSale.toString())
        // props.history.push(`/business/${newSale}.toString/sales/invoice`,{prevIoUsLocation: props.location.pathname})
      } else {
        setIsCreatingNewSale(false)
        const payload = response.payload
        const errs = responseErrorParser(payload.data)
        setTimeout(() => {
            errs.forEach(e => toast.error(e.message))
        },400);
      }
    }
  }

  return(
    <Fragment>
      <div style={{display:"flex",fontFamily:"'Poppins',sans-serif"}}>
        <div className="col-lg-10"  style={{margin: "0 auto",maxWidth:"500px",width:"100%"}}>
          <Form>
            <Card>
              <CardBody>
                <FormGroup>
                  <Label>Customer Name</Label>
                  <Typeahead
                    id="basic-typeahead"
                    labelKey="name"
                    onChange={setCustomerName}
                    options={customerOptions}
                    selected={customerName}
                    value={customerName}
                    name="customerName"
                    style={{backgroundColor:"#d5deee"}}
                  />
                </FormGroup>
              </CardBody>
            </Card>
            { newProductValues.map((newProductValue,index) => (
              <div key={index}>
                <Card >
                  <CardBody>
                    <Col style={{textAlign: "right"}}>
                      <i onClick={() => handleRemoveFields()} >{trash2}</i>
                    </Col>
                    <ProductCard index={index} handleChange={handleChange} value={newProductValue} />
                  </CardBody>
                </Card>
              </div>  
            ))}
            <Row>
              <Col>
                <p onClick={() => handleAddFields()} style={{marginLeft:"20px"}}> <span style={{fontSize:"18px"}}>+</span> Add another product</p>
              </Col>
            </Row>
              <Row>
                <Col>
                  <p onClick={() => handleAddFields()} style={{marginLeft:"20px"}}> <span style={{fontSize:"18px"}}>+</span> Add another product</p>
                </Col>
              </Row>
            <Card>
              <CardBody>
                <FormGroup>
                  <div className="form-row">
                    <Col>
                      <Label for="date">Date</Label>
                      <Input className="form-control digits" type="date" defaultValue="2018-01-01" value={date} onChange={e => setDate(e.target.value)} id="date" name="date" style={{backgroundColor:"#d5deee"}} />
                    </Col>
                    <Col>
                      <Label for="dueDate">Due Date</Label>
                      <Input className="form-control digits" type="date" defaultValue="2018-01-01" value={dueDate} onChange={e => setDueDate(e.target.value)} id="dueDate" name="dueDate" style={{backgroundColor:"#d5deee"}} />
                    </Col>
                  </div>
                </FormGroup>
                <FormGroup>
                  <div className="form-row">
                    <Col>
                      <Label for="vat">VAT %</Label>
                      <Input type="text" id="vat" value={vat} onChange={e => setVat(e.target.value)} style={{backgroundColor:"#d5deee"}} />
                    </Col>
                  </div>
                </FormGroup>
                <div style={{margin:"0 auto",textAlign:"center"}}>
                  <p style={{fontSize:"12px"}}>Only click cleared if this sales have been paid in full</p>
                  <Row>
                    <Col>
                      <ButtonGroup>
                        <Button outline color="primary" type="button">Cleared</Button>
                        <Button outline color="primary" type="button">Not Cleared</Button>
                      </ButtonGroup>
                    </Col>
                  </Row>
                </div>
                <Row className="m-t-50">
                  <Col lg={`6`}>
                    <Button outline color="primary" size="lg" style={{maxWidth:"200px",width:"100%"}}>SAVE</Button>
                  </Col>
                  <Col lg={`6`}>
                    <Button color="primary" size="lg" onClick={e => handleCreateNewSale(e)} style={{maxWidth:"200px",width:"100%"}}>CREATE</Button>
                  </Col>
                </Row>
              </CardBody>
            </Card>
          </Form>
        </div>
        <div className="col-lg-2" style={{backgroundColor:"#eaf6fd",position:"fixed",right:0,height:"100%",}}>
          <Card className="m-t-50">
            <CardBody>
              <div>You have added <span>0</span> products</div>              
            </CardBody>
          </Card>
          <div className="table-responsive">
            <Table borderless>
              <tbody>
                <tr>
                  <td className="bd-t-none">Sub Total</td>
                  <td>000 000 000</td>
                </tr>
                <tr style={{fontWeight:"bold"}}>
                  <td className="bd-t-none">Total</td>
                  <td>000 000 000</td>
                </tr>
              </tbody>
            </Table>
          </div>
        </div>
      </div>
    </Fragment>
  )
}

const mapStatetoProps = (state) => ({
  requestingCreateNewSale: state.isRequestingCreateNewSale,});

const actions = {
  CreateNewSale: CreateNewSale
};

export default connect(mapStatetoProps,actions)(withRouter(CreateNewSale))

这是我每次想更改productName typeahead值时都会不断收到的错误

TypeError: Cannot read property 'name' of undefined
handleChange
src/pages/sales/CreateNewSales.js:54
  51 | const handleChange = (event,index) => {
  52 |   console.log( event )
  53 |   const values = [...newProductValues];
> 54 |   values[index][event.target.name] = event.target.value
     | ^  55 |   console.log('=======================>',values)
  56 |   setNewProductValues(values);
  57 |   // setNewProductValues({
View compiled
onChange
src/components/sales/ProductCard.jsx:40
  37 | <Typeahead
  38 |   id="basic-typeahead"
  39 |   labelKey="name"
> 40 |   onChange={(e) => props.handleChange(e,props.index)}
     | ^  41 |   // onInputChange={props.setProductName}
  42 |   options={ProductOptions}
  43 |   name={ProductOptions}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...