Reactjs 如何解决react引导typeahead的此错误

Reactjs 如何解决react引导typeahead的此错误,reactjs,input,react-bootstrap,typeahead,react-bootstrap-typeahead,Reactjs,Input,React Bootstrap,Typeahead,React Bootstrap Typeahead,我有一个名为ProductCard的子组件,它从名为CreateNewSales的父组件获取道具。onChange函数有两个参数,在父函数中定义。如果我在ProductCard中调用该函数,我会继续得到typeahead的这个错误,尽管除了数量输入之外的其他输入似乎都正常工作。代码如下: 这是产品卡: import React, { useState, Fragment } from 'react'; import { FormGroup, Label, Input, Col} from 're

我有一个名为ProductCard的子组件,它从名为CreateNewSales的父组件获取道具。onChange函数有两个参数,在父函数中定义。如果我在ProductCard中调用该函数,我会继续得到typeahead的这个错误,尽管除了数量输入之外的其他输入似乎都正常工作。代码如下:

这是产品卡:

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
import React,{useState,Fragment}来自“React”;
从“reactstrap”导入{FormGroup,Label,Input,Col};
从'react bootstrap Typeahead'导入{Typeahead};
从“道具类型”导入道具类型;
从“react feather”导入{PlusSquare,MinusSquare}
常数加平方=
常数平方=
const ProductCard=(道具)=>{
控制台日志(道具)
const ProductOptions=[{id:1,name:“costs”},{id:2,name:“Services”},{id:3,name:“Shows”},{id:4,name:“Peace”}]//虚拟日期//res_data.payload.data.product
//常量[singleSelections,setSingleSelections]=useState([]);
//来自quantityIncrement.js
const[count,setCount]=useState(1)
常数减量=()=>{
如果(计数==1){
设置计数(计数)
}否则{
设置计数(计数-1)
}
};
常量增量=()=>{
设置计数(计数+1)
};
返回(
品名
props.handleChange(e,props.index)}
//onInputChange={props.setProductName}
选项={ProductOptions}
名称={ProductOptions}
所选={props.value.productName}
风格={{backgroundColor:{d5deee}
value={props.value.productName}
/>
量
setCount(e.target.value)}style={{{backgroundColor:“#d5deee”}}/>
{plusSquare}{minusSquare}
优惠
props.handleChange(e,props.index)}value={props.value.discount}name=“discount”style={{{{backgroundColor:“#d5deee”}}/>
价格
props.handleChange(e,props.index)}value={props.value.price}name=“price”style={{{{backgroundColor:“#d5deee”}}/>
已付金额
props.handleChange(e,props.index)}value={props.value.amountpayed}name=“amountpayed”style={{{backgroundColor:“#d5deee”}/>
)
}
ProductCard.propTypes={
handleChange:PropTypes.func.isRequired,
值:PropTypes.object.isRequired,
//onClickQuantity:PropTypes.func.isRequired
}
导出默认产品卡
这是CreateNewSale:

import React, { Fragment, useState } from 'react';
import {Form, FormGroup, Label, Input, 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:"", price: "",
    amountPaid: "",
    quantity: "1",
    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"}, {id:4,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: '', message: 'Please enter an already created customer name' },
    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))
import React,{Fragment,useState}来自'React';
从“reactstrap”导入{Form,FormGroup,Label,Input,Card,Col,Row,CardBody,Button,ButtonGroup,Table};
从'react toastify'导入{toast};
从'react bootstrap Typeahead'导入{Typeahead};
从“react router”导入{withRouter};
//从'react router dom'导入{useHistory};
从'react redux'导入{connect};
从“./../components/authentication/validator”导入{validateCreateNewSaleForm,responseErrorParser}
//productCard.js
从“../../components/sales/ProductCard”导入ProductCard
从“react feather”导入{Trash2}
常量垃圾2=
const CreateNewSale=(道具)=>{
const[,setIsCreatingNewSale]=使用状态(false)
//常量[singleSelections,setSingleSelections]=useState([]);
//从productCard.js
常量[newProductValues,setNewProductValues]=useState([{
产品名称:[],
折扣:“,
价格:“,
已付金额:“,
数量:“1”,
}]);
//常量[newProductName,setNewProductName]=useState([{
//新产品名称:[],
//新客户名称:[]
// }])
//常量handleInputChange=(事件)=>{
//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)
常量handleChange=(事件、索引)=>{
console.log(事件)
常量值=[…newProductValues];
值[index][event.target.name]=event.target.value
console.log('=========================>',值)
setNewProductValues(值);
//SetNewProductValue({
//…新产品价值观,
//[event.target.name]:event.target.value
// });
}
const handleaddields=(e)=>{
setNewProductValues([…newProductValues,{折扣:,价格:,
已付金额:“,
数量:“1”,
产品名称:[]
}])
}
常量handleRemoveFields=(索引)=>{
常量值=[…newProductValues];
拼接值(索引1);
setNewProductValues(值);
}
const customerOptions=[{id:1,name:“Olalekan”},{id:2,name:“Michael”},{id:3,name:“Emeka”},{id:4,name:“glori”}]//虚拟数据//res_data.payload.data.customer
常量字段={
客户名称:{默认值:'',消息:'请输入已创建的客户名称'},
产品名称:{默认值:'',消息:'请输入已创建的客户名称'},
数量:{默认值:'',消息:'请选择一个数量'},
折扣:{默认值:'',消息:'请输入给定的折扣'},
价格:{默认值:'',消息:'请选择给定的价格'},
支付金额:{默认值:'',消息:'请输入客户支付的金额',
日期:{默认值:'',消息:'请输入日期'},
到期日:{默认值:'',消息:'请输入给定的到期日'},
增值税:{默认值:'',消息:'请输入增值税'},
}
const handleCreateNewSale=async(e)=>{
e、 预防默认值()
setIsCreatingNewSale(真);
const responsePayload={
客户名称:newProductValues.newCustomerName,//customerName
产品名称:newProductValues.newproductNames,
数量:新台币
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}