如何解决如何解决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 举报,一经查实,本站将立刻删除。